From 46d43c247f8e4977a7c1bc0625681e134ac9364b Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 9 Oct 2023 15:51:45 +0800 Subject: [PATCH 001/134] Update light.css --- web/css/light.css | 1 - 1 file changed, 1 deletion(-) diff --git a/web/css/light.css b/web/css/light.css index e8c58d1b..e881dcb5 100644 --- a/web/css/light.css +++ b/web/css/light.css @@ -3,7 +3,6 @@ body { background: #ebebeb url('../img/light.png'); } .navbar-brand { color: #fff; padding: 10px; font-size: 20px; } .dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; } .navbar-inverse .navbar-brand { color: #fff; padding: 10px; font-size: 20px; } -.container { width: 1280px; } .content { background: #ffffff; padding: 20px; border-radius: 5px; border: 1px #cecece solid; -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); box-shadow: 0 1px 10px rgba(0, 0, 0, .1); margin-bottom: 20px; } .table { background: #ffffff; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; } .table th, .table td { text-align: center; } From be78a7cc88946c0c1ca10eafb4e8fde9ebc57437 Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 11:45:12 +0800 Subject: [PATCH 002/134] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 28922436..bf4961c4 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ cd ServerStatus/server && make }, { "name": "服务器宕机告警,排除经常掉线的", - "rule": "online4=0&online6=0&username!=s21", + "rule": "online4=0&online6=0&name!=俄勒冈", "interval": 600, "callback": "https://yourSMSurl" }, From a5330dcf2fde4d17da0dd78c10613e2e73133eab Mon Sep 17 00:00:00 2001 From: windows11 Date: Fri, 13 Oct 2023 11:58:46 +0800 Subject: [PATCH 003/134] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dusername=E7=AD=89?= =?UTF-8?q?=E9=9D=99=E6=80=81=E5=8F=98=E9=87=8F=E7=9A=84=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index 61ab9fa3..f769a2ca 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -271,7 +271,13 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl typedef exprtk::parser parser_t; const std::string expression_string = Watchdog(ID)->m_aRule; + int ClientID = ClientNetToClient(ClientNetID); symbol_table_t symbol_table; + symbol_table.add_variable("username", Client(ClientID)->m_aUsername); + symbol_table.add_variable("name", Client(ClientID)->m_aName); + symbol_table.add_variable("type", Client(ClientID)->m_aType); + symbol_table.add_variable("host", Client(ClientID)->m_aHost); + symbol_table.add_variable("location", Client(ClientID)->m_aLocation); symbol_table.add_variable("load_1",load_1); symbol_table.add_variable("load_5",load_5); symbol_table.add_variable("load_15",load_15); @@ -310,7 +316,6 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl if (expression.value() > 0) { - int ClientID = ClientNetToClient(ClientNetID); time_t currentStamp = (long long)time(/*ago*/0); if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval) { From fdca4fd3537284245a964c01778e3bb0614b4fb2 Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 12:30:03 +0800 Subject: [PATCH 004/134] =?UTF-8?q?=E9=9D=99=E6=80=81=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E5=8F=98=E9=87=8F=E6=97=A0=E6=B3=95=E5=8F=82=E4=B8=8E?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 静态字符串变量无法参与计算。 --- server/src/main.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index f769a2ca..eb4feaa1 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -271,13 +271,7 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl typedef exprtk::parser parser_t; const std::string expression_string = Watchdog(ID)->m_aRule; - int ClientID = ClientNetToClient(ClientNetID); symbol_table_t symbol_table; - symbol_table.add_variable("username", Client(ClientID)->m_aUsername); - symbol_table.add_variable("name", Client(ClientID)->m_aName); - symbol_table.add_variable("type", Client(ClientID)->m_aType); - symbol_table.add_variable("host", Client(ClientID)->m_aHost); - symbol_table.add_variable("location", Client(ClientID)->m_aLocation); symbol_table.add_variable("load_1",load_1); symbol_table.add_variable("load_5",load_5); symbol_table.add_variable("load_15",load_15); @@ -316,6 +310,7 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl if (expression.value() > 0) { + int ClientID = ClientNetToClient(ClientNetID); time_t currentStamp = (long long)time(/*ago*/0); if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval) { From 03682772a12805c1d1b0a593bd6500dc0832a308 Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 12:46:25 +0800 Subject: [PATCH 005/134] =?UTF-8?q?=E9=9D=99=E6=80=81=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E6=97=A0=E6=B3=95=E5=8F=82=E4=B8=8E=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提交一个表达式说明,静态字符串无法参与计算 --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bf4961c4..b901b7d3 100644 --- a/README.md +++ b/README.md @@ -67,9 +67,9 @@ cd ServerStatus/server && make #### 二、修改配置文件 ```diff -! watchdog rule 可以为任何已知字段的表达式。 -! watchdog interval 最小通知间隔。 -! watchdog callback 可自定义为Post方法的URL,告警内容将拼接其后并发起回调。 +! watchdog rule 可以为任何已知字段的表达式(不包括name, type, host, location, uptime,字符串无法参与计算) +! watchdog interval 最小通知间隔 +! watchdog callback 可自定义为Post方法的URL,告警内容将拼接其后并发起回调 ! watchdog callback Telegram: https://api.telegram.org/bot你自己的密钥/sendMessage?parse_mode=HTML&disable_web_page_preview=true&chat_id=你自己的标识&text= ! watchdog callback Server酱: https://sctapi.ftqq.com/你自己的密钥.send?title=ServerStatus&desp= @@ -106,8 +106,8 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "服务器宕机告警,排除经常掉线的", - "rule": "online4=0&online6=0&name!=俄勒冈", + "name": "服务器宕机告警,排除海外机器", + "rule": "online4=0&online6=0&time_10010<160&time_189<160&time_10086<160", "interval": 600, "callback": "https://yourSMSurl" }, From a8383efe936e5f259235acd0e55c9eec4e45c9cb Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 12:47:24 +0800 Subject: [PATCH 006/134] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b901b7d3..39832898 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ cd ServerStatus/server && make #### 二、修改配置文件 ```diff -! watchdog rule 可以为任何已知字段的表达式(不包括name, type, host, location, uptime,字符串无法参与计算) +! watchdog rule 可以为任何已知字段的表达式(不包括name, type, host, location, uptime,字符串无法参与计算) ! watchdog interval 最小通知间隔 ! watchdog callback 可自定义为Post方法的URL,告警内容将拼接其后并发起回调 From 67877bacfcf3464050ab3d03b8bae0280688bc22 Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 13:11:46 +0800 Subject: [PATCH 007/134] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 39832898..6da59bbc 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,8 @@ cd ServerStatus/server && make "watchdog": [ { - "name": "服务器负载高监控", - "rule": "cpu>90&load_5>3", + "name": "服务器负载高监控,排除物理机", + "rule": "cpu>90&load_1>4&load_5<10", "interval": 600, "callback": "https://yourSMSurl" }, From 3ef6cb52c1e782d130dcd4e4412d2dcc32095606 Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 13:13:05 +0800 Subject: [PATCH 008/134] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6da59bbc..dd9b72db 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,8 @@ cd ServerStatus/server && make "watchdog": [ { - "name": "服务器负载高监控,排除物理机", - "rule": "cpu>90&load_1>4&load_5<10", + "name": "服务器负载高监控,排除负载一直大于15的物理机", + "rule": "cpu>90&load_1>4&load_5<15", "interval": 600, "callback": "https://yourSMSurl" }, From da83c54e5bf39c6293997d93cf91cc952fe0dfe0 Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 13:34:18 +0800 Subject: [PATCH 009/134] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dd9b72db..15d07b20 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,8 @@ cd ServerStatus/server && make "watchdog": [ { - "name": "服务器负载高监控,排除负载一直大于15的物理机", - "rule": "cpu>90&load_1>4&load_5<15", + "name": "服务器负载高监控,排除内存大于32G物理机", + "rule": "cpu>90&load_1>4&memory_total<33554432", "interval": 600, "callback": "https://yourSMSurl" }, From 2e0d1f7fb9868fc29130a38917863942b8f2c2bf Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 13:53:20 +0800 Subject: [PATCH 010/134] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 15d07b20..10fbb66d 100644 --- a/README.md +++ b/README.md @@ -106,8 +106,8 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "服务器宕机告警,排除海外机器", - "rule": "online4=0&online6=0&time_10010<160&time_189<160&time_10086<160", + "name": "服务器宕机告警,闪断引起的误报问题等待解决", + "rule": "online4=0&online6=0", "interval": 600, "callback": "https://yourSMSurl" }, From 7bbca5e881d0b98f2ab4122058db680936a83e7e Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 13 Oct 2023 13:54:02 +0800 Subject: [PATCH 011/134] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10fbb66d..46997f76 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "服务器宕机告警,闪断引起的误报问题等待解决", + "name": "服务器宕机告警", "rule": "online4=0&online6=0", "interval": 600, "callback": "https://yourSMSurl" From 77cb62ae803de455f8255191b693c8bc2dcbd0b6 Mon Sep 17 00:00:00 2001 From: windows11 Date: Mon, 16 Oct 2023 16:57:02 +0800 Subject: [PATCH 012/134] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=9D=99=E6=80=81=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/exprtk.hpp | 1507 ++++++++++++++++++++++++----------------- server/src/main.cpp | 22 +- 2 files changed, 888 insertions(+), 641 deletions(-) diff --git a/server/src/exprtk.hpp b/server/src/exprtk.hpp index eebadb57..b4530ba0 100644 --- a/server/src/exprtk.hpp +++ b/server/src/exprtk.hpp @@ -2,7 +2,7 @@ ****************************************************************** * C++ Mathematical Expression Toolkit Library * * * - * Author: Arash Partow (1999-2022) * + * Author: Arash Partow (1999-2023) * * URL: https://www.partow.net/programming/exprtk/index.html * * * * Copyright notice: * @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -298,7 +297,6 @@ namespace exprtk std::reverse(result.begin(), result.end()); - return result; } @@ -401,7 +399,7 @@ namespace exprtk { public: - build_string(const std::size_t& initial_size = 64) + explicit build_string(const std::size_t& initial_size = 64) { data_.reserve(initial_size); } @@ -597,15 +595,13 @@ namespace exprtk } }; - template ::value_type> + template inline bool match_impl(const Iterator pattern_begin, const Iterator pattern_end , const Iterator data_begin , const Iterator data_end , - const ValueType zero_or_more, - const ValueType exactly_one ) + const typename std::iterator_traits::value_type& zero_or_more, + const typename std::iterator_traits::value_type& exactly_one ) { typedef typename std::iterator_traits::value_type type; @@ -665,7 +661,7 @@ namespace exprtk inline bool wc_match(const std::string& wild_card, const std::string& str) { - return match_impl( + return match_impl( wild_card.data(), wild_card.data() + wild_card.size(), str.data(), @@ -676,7 +672,7 @@ namespace exprtk inline bool wc_imatch(const std::string& wild_card, const std::string& str) { - return match_impl( + return match_impl( wild_card.data(), wild_card.data() + wild_card.size(), str.data(), @@ -784,7 +780,6 @@ namespace exprtk { struct unknown_type_tag { unknown_type_tag() {} }; struct real_type_tag { real_type_tag () {} }; - struct complex_type_tag { complex_type_tag() {} }; struct int_type_tag { int_type_tag () {} }; template @@ -798,10 +793,6 @@ namespace exprtk template <> struct number_type \ { typedef real_type_tag type; number_type() {} }; \ - #define exprtk_register_complex_type_tag(T) \ - template <> struct number_type > \ - { typedef complex_type_tag type; number_type() {} }; \ - #define exprtk_register_int_type_tag(T) \ template <> struct number_type \ { typedef int_type_tag type; number_type() {} }; \ @@ -810,10 +801,6 @@ namespace exprtk exprtk_register_real_type_tag(long double) exprtk_register_real_type_tag(float ) - exprtk_register_complex_type_tag(double ) - exprtk_register_complex_type_tag(long double) - exprtk_register_complex_type_tag(float ) - exprtk_register_int_type_tag(short ) exprtk_register_int_type_tag(int ) exprtk_register_int_type_tag(_int64_t ) @@ -2073,6 +2060,11 @@ namespace exprtk details::_uint64_t iteration_count; }; + virtual bool check() + { + return true; + } + virtual void handle_runtime_violation(const violation_context&) { throw std::runtime_error("ExprTk Loop run-time violation."); @@ -3328,7 +3320,7 @@ namespace exprtk ignore_set_.insert(symbol); } - inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) + inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) exprtk_override { bool match = false; new_token.type = lexer::token::e_mul; @@ -3383,7 +3375,7 @@ namespace exprtk : token_joiner(stride) {} - inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) + inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) exprtk_override { // ': =' --> ':=' if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq)) @@ -3531,7 +3523,7 @@ namespace exprtk inline bool join(const lexer::token& t0, const lexer::token& t1, const lexer::token& t2, - lexer::token& t) + lexer::token& t) exprtk_override { // '[ * ]' --> '[*]' if ( @@ -3637,7 +3629,7 @@ namespace exprtk }; template - class numeric_checker : public lexer::token_scanner + class numeric_checker exprtk_final : public lexer::token_scanner { public: @@ -3767,7 +3759,7 @@ namespace exprtk replace_map_t replace_map_; }; - class sequence_validator : public lexer::token_scanner + class sequence_validator exprtk_final : public lexer::token_scanner { private: @@ -3939,7 +3931,7 @@ namespace exprtk std::vector > error_list_; }; - class sequence_validator_3tokens : public lexer::token_scanner + class sequence_validator_3tokens exprtk_final : public lexer::token_scanner { private: @@ -4773,12 +4765,12 @@ namespace exprtk inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0) { if (size) - exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr)); - else exprtk_debug(("%s - addr: %p size: %d\n", s.c_str(), ptr, static_cast(size))); + else + exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr)); } #else inline void dump_ptr(const std::string&, const void*) {} @@ -4822,7 +4814,7 @@ namespace exprtk { if (data && destruct && (0 == ref_count)) { - dump_ptr("~control_block() data",data); + dump_ptr("~vec_data_store::control_block() data",data); delete[] data; data = reinterpret_cast(0); } @@ -5235,12 +5227,6 @@ namespace exprtk return std::not_equal_to()(0.0f,v); } - template - inline bool is_true(const std::complex& v) - { - return std::not_equal_to >()(std::complex(0),v); - } - template inline bool is_true(const expression_node* node) { @@ -5957,16 +5943,16 @@ namespace exprtk : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size)) {} - vector_holder(const vds_t& vds) + explicit vector_holder(const vds_t& vds) : vector_holder_base_(new(buffer)array_vector_impl(vds.data(),vds.size())) {} template - vector_holder(std::vector& vec) + explicit vector_holder(std::vector& vec) : vector_holder_base_(new(buffer)sequence_vector_impl(vec)) {} - vector_holder(exprtk::vector_view& vec) + explicit vector_holder(exprtk::vector_view& vec) : vector_holder_base_(new(buffer)vector_view_impl(vec)) {} @@ -6084,9 +6070,9 @@ namespace exprtk const bool result = details::numeric::is_nan(v); if (result) - return (equality_) ? T(1) : T(0); + return equality_ ? T(1) : T(0); else - return (equality_) ? T(0) : T(1); + return equality_ ? T(0) : T(1); } inline typename expression_node::node_type type() const exprtk_override @@ -6270,9 +6256,7 @@ namespace exprtk inline T value() const exprtk_override { assert(branch_.first); - const T arg = branch_.first->value(); - return numeric::process(operation_,arg); } @@ -6301,12 +6285,12 @@ namespace exprtk expression_node::ndb_t::collect(branch_, node_delete_list); } - std::size_t node_depth() const exprtk_override exprtk_final + std::size_t node_depth() const exprtk_final { return expression_node::ndb_t::compute_node_depth(branch_); } - protected: + private: operator_type operation_; branch_t branch_; @@ -6336,7 +6320,7 @@ namespace exprtk const T arg0 = branch_[0].first->value(); const T arg1 = branch_[1].first->value(); - return numeric::process(operation_,arg0,arg1); + return numeric::process(operation_, arg0, arg1); } inline typename expression_node::node_type type() const exprtk_override @@ -6364,12 +6348,12 @@ namespace exprtk expression_node::ndb_t::template collect(branch_, node_delete_list); } - std::size_t node_depth() const exprtk_override exprtk_final + std::size_t node_depth() const exprtk_final { return expression_node::ndb_t::template compute_node_depth<2>(branch_); } - protected: + private: operator_type operation_; branch_t branch_[2]; @@ -6748,7 +6732,7 @@ namespace exprtk { if ( (0 == loop_runtime_check_) || - (++iteration_count_ <= max_loop_iterations_) + ((++iteration_count_ <= max_loop_iterations_) && loop_runtime_check_->check()) ) { return true; @@ -8184,6 +8168,8 @@ namespace exprtk typedef vector_node * vector_node_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + swap_vecvec_node(expression_ptr branch0, expression_ptr branch1) : binary_node(details::e_swap, branch0, branch1) @@ -8192,22 +8178,22 @@ namespace exprtk , vec_size_ (0) , initialised_ (false) { - if (is_ivector_node(binary_node::branch_[0].first)) + if (is_ivector_node(branch(0))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[0].first))) + if (0 != (vi = dynamic_cast*>(branch(0)))) { vec0_node_ptr_ = vi->vec(); vds() = vi->vds(); } } - if (is_ivector_node(binary_node::branch_[1].first)) + if (is_ivector_node(branch(1))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[1].first))) + if (0 != (vi = dynamic_cast*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); } @@ -8228,11 +8214,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + binary_node::branch(0)->value(); + binary_node::branch(1)->value(); T* vec0 = vec0_node_ptr_->vds().data(); T* vec1 = vec1_node_ptr_->vds().data(); @@ -8693,6 +8679,8 @@ namespace exprtk typedef expression_node * expression_ptr; typedef string_base_node* str_base_ptr; + using binary_node::branch; + string_concat_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -8709,27 +8697,27 @@ namespace exprtk range_.cache.first = range_.n0_c.second; range_.cache.second = range_.n1_c.second; - if (is_generally_string_node(binary_node::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); + str0_base_ptr_ = dynamic_cast(branch(0)); if (0 == str0_base_ptr_) return; - str0_range_ptr_ = dynamic_cast(binary_node::branch_[0].first); + str0_range_ptr_ = dynamic_cast(branch(0)); if (0 == str0_range_ptr_) return; } - if (is_generally_string_node(binary_node::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); + str1_base_ptr_ = dynamic_cast(branch(1)); if (0 == str1_base_ptr_) return; - str1_range_ptr_ = dynamic_cast(binary_node::branch_[1].first); + str1_range_ptr_ = dynamic_cast(branch(1)); if (0 == str1_range_ptr_) return; @@ -8747,11 +8735,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t str0_r0 = 0; std::size_t str0_r1 = 0; @@ -8838,20 +8826,22 @@ namespace exprtk typedef stringvar_node * strvar_node_ptr; typedef string_base_node* str_base_ptr; + using binary_node::branch; + swap_string_node(expression_ptr branch0, expression_ptr branch1) : binary_node(details::e_swap, branch0, branch1), initialised_(false), str0_node_ptr_(0), str1_node_ptr_(0) { - if (is_string_node(binary_node::branch_[0].first)) + if (is_string_node(branch(0))) { - str0_node_ptr_ = static_cast(binary_node::branch_[0].first); + str0_node_ptr_ = static_cast(branch(0)); } - if (is_string_node(binary_node::branch_[1].first)) + if (is_string_node(branch(1))) { - str1_node_ptr_ = static_cast(binary_node::branch_[1].first); + str1_node_ptr_ = static_cast(branch(1)); } initialised_ = (str0_node_ptr_ && str1_node_ptr_); @@ -8863,11 +8853,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref()); } @@ -8924,6 +8914,8 @@ namespace exprtk typedef expression_node * expression_ptr; typedef string_base_node* str_base_ptr; + using binary_node::branch; + swap_genstrings_node(expression_ptr branch0, expression_ptr branch1) : binary_node(details::e_default, branch0, branch1) @@ -8933,14 +8925,14 @@ namespace exprtk , str1_range_ptr_(0) , initialised_(false) { - if (is_generally_string_node(binary_node::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); + str0_base_ptr_ = dynamic_cast(branch(0)); if (0 == str0_base_ptr_) return; - irange_ptr range = dynamic_cast(binary_node::branch_[0].first); + irange_ptr range = dynamic_cast(branch(0)); if (0 == range) return; @@ -8948,14 +8940,14 @@ namespace exprtk str0_range_ptr_ = &(range->range_ref()); } - if (is_generally_string_node(binary_node::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); + str1_base_ptr_ = dynamic_cast(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast(binary_node::branch_[1].first); + irange_ptr range = dynamic_cast(branch(1)); if (0 == range) return; @@ -8975,11 +8967,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t str0_r0 = 0; std::size_t str0_r1 = 0; @@ -9189,6 +9181,8 @@ namespace exprtk typedef stringvar_node * strvar_node_ptr; typedef string_base_node* str_base_ptr; + using binary_node::branch; + assignment_string_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -9199,21 +9193,20 @@ namespace exprtk , str0_node_ptr_ (0) , str1_range_ptr_(0) { - if (is_string_node(binary_node::branch_[0].first)) + if (is_string_node(branch(0))) { - str0_node_ptr_ = static_cast(binary_node::branch_[0].first); - - str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); + str0_node_ptr_ = static_cast(branch(0)); + str0_base_ptr_ = dynamic_cast(branch(0)); } - if (is_generally_string_node(binary_node::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); + str1_base_ptr_ = dynamic_cast(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast(binary_node::branch_[1].first); + irange_ptr range = dynamic_cast(branch(1)); if (0 == range) return; @@ -9233,10 +9226,10 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[1].first->value(); + branch(1)->value(); std::size_t r0 = 0; std::size_t r1 = 0; @@ -9249,7 +9242,7 @@ namespace exprtk str1_base_ptr_->base() + r0, (r1 - r0) + 1); - binary_node::branch_[0].first->value(); + branch(0)->value(); } } @@ -9312,6 +9305,8 @@ namespace exprtk typedef string_range_node* str_rng_node_ptr; typedef string_base_node * str_base_ptr; + using binary_node::branch; + assignment_string_range_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -9323,13 +9318,11 @@ namespace exprtk , str0_range_ptr_ (0) , str1_range_ptr_ (0) { - if (is_string_range_node(binary_node::branch_[0].first)) + if (is_string_range_node(branch(0))) { - str0_rng_node_ptr_ = static_cast(binary_node::branch_[0].first); - - str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); - - irange_ptr range = dynamic_cast(binary_node::branch_[0].first); + str0_rng_node_ptr_ = static_cast(branch(0)); + str0_base_ptr_ = dynamic_cast(branch(0)); + irange_ptr range = dynamic_cast(branch(0)); if (0 == range) return; @@ -9337,14 +9330,14 @@ namespace exprtk str0_range_ptr_ = &(range->range_ref()); } - if (is_generally_string_node(binary_node::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); + str1_base_ptr_ = dynamic_cast(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast(binary_node::branch_[1].first); + irange_ptr range = dynamic_cast(branch(1)); if (0 == range) return; @@ -9365,11 +9358,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t s0_r0 = 0; std::size_t s0_r1 = 0; @@ -9616,6 +9609,8 @@ namespace exprtk typedef expression_node * expression_ptr; typedef string_base_node* str_base_ptr; + using binary_node::branch; + cons_conditional_str_node(expression_ptr condition, expression_ptr consequent) : binary_node(details::e_default, consequent, condition) @@ -9631,14 +9626,14 @@ namespace exprtk range_.cache.first = range_.n0_c.second; range_.cache.second = range_.n1_c.second; - if (is_generally_string_node(binary_node::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); + str0_base_ptr_ = dynamic_cast(branch(0)); if (0 == str0_base_ptr_) return; - str0_range_ptr_ = dynamic_cast(binary_node::branch_[0].first); + str0_range_ptr_ = dynamic_cast(branch(0)); if (0 == str0_range_ptr_) return; @@ -10364,6 +10359,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; assignment_node(const operator_type& opr, expression_ptr branch0, @@ -10371,9 +10367,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , var_node_ptr_(0) { - if (is_variable_node(binary_node::branch_[0].first)) + if (is_variable_node(branch(0))) { - var_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + var_node_ptr_ = static_cast*>(branch(0)); } } @@ -10381,11 +10377,10 @@ namespace exprtk { if (var_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& result = var_node_ptr_->ref(); - - result = binary_node::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10404,6 +10399,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; assignment_vec_elem_node(const operator_type& opr, expression_ptr branch0, @@ -10411,9 +10407,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_elem_node(binary_node::branch_[0].first)) + if (is_vector_elem_node(branch(0))) { - vec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + vec_node_ptr_ = static_cast*>(branch(0)); } } @@ -10421,11 +10417,10 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& result = vec_node_ptr_->ref(); - - result = binary_node::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10444,6 +10439,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using expression_node::branch; assignment_rebasevec_elem_node(const operator_type& opr, expression_ptr branch0, @@ -10451,9 +10447,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_elem_node(binary_node::branch_[0].first)) + if (is_rebasevector_elem_node(branch(0))) { - rbvec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + rbvec_node_ptr_ = static_cast*>(branch(0)); } } @@ -10461,11 +10457,11 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& result = rbvec_node_ptr_->ref(); - result = binary_node::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10484,6 +10480,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; assignment_rebasevec_celem_node(const operator_type& opr, expression_ptr branch0, @@ -10491,9 +10488,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_celem_node(binary_node::branch_[0].first)) + if (is_rebasevector_celem_node(branch(0))) { - rbvec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + rbvec_node_ptr_ = static_cast*>(branch(0)); } } @@ -10501,11 +10498,10 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& result = rbvec_node_ptr_->ref(); - - result = binary_node::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10529,15 +10525,17 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + assignment_vec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) : binary_node(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_node(binary_node::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + vec_node_ptr_ = static_cast*>(branch(0)); vds() = vec_node_ptr_->vds(); } } @@ -10546,9 +10544,9 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); - const T v = binary_node::branch_[1].first->value(); + const T v = branch(1)->value(); T* vec = vds().data(); @@ -10649,6 +10647,8 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + assignment_vecvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -10658,22 +10658,22 @@ namespace exprtk , initialised_(false) , src_is_ivec_(false) { - if (is_vector_node(binary_node::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + vec0_node_ptr_ = static_cast*>(branch(0)); vds() = vec0_node_ptr_->vds(); } - if (is_vector_node(binary_node::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast*>(binary_node::branch_[1].first); + vec1_node_ptr_ = static_cast*>(branch(1)); vds_t::match_sizes(vds(),vec1_node_ptr_->vds()); } - else if (is_ivector_node(binary_node::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[1].first))) + if (0 != (vi = dynamic_cast*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); @@ -10696,9 +10696,9 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); - binary_node::branch_[1].first->value(); + branch(1)->value(); if (src_is_ivec_) return vec0_node_ptr_->value(); @@ -10802,6 +10802,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; assignment_op_node(const operator_type& opr, expression_ptr branch0, @@ -10809,9 +10810,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , var_node_ptr_(0) { - if (is_variable_node(binary_node::branch_[0].first)) + if (is_variable_node(branch(0))) { - var_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + var_node_ptr_ = static_cast*>(branch(0)); } } @@ -10819,10 +10820,10 @@ namespace exprtk { if (var_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& v = var_node_ptr_->ref(); - v = Operation::process(v,binary_node::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10841,6 +10842,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; assignment_vec_elem_op_node(const operator_type& opr, expression_ptr branch0, @@ -10848,9 +10850,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_elem_node(binary_node::branch_[0].first)) + if (is_vector_elem_node(branch(0))) { - vec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + vec_node_ptr_ = static_cast*>(branch(0)); } } @@ -10858,10 +10860,10 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& v = vec_node_ptr_->ref(); - v = Operation::process(v,binary_node::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10880,6 +10882,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; assignment_rebasevec_elem_op_node(const operator_type& opr, expression_ptr branch0, @@ -10887,9 +10890,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_elem_node(binary_node::branch_[0].first)) + if (is_rebasevector_elem_node(branch(0))) { - rbvec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + rbvec_node_ptr_ = static_cast*>(branch(0)); } } @@ -10897,10 +10900,10 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& v = rbvec_node_ptr_->ref(); - v = Operation::process(v,binary_node::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10919,6 +10922,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; assignment_rebasevec_celem_op_node(const operator_type& opr, expression_ptr branch0, @@ -10926,9 +10930,9 @@ namespace exprtk : binary_node(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_celem_node(binary_node::branch_[0].first)) + if (is_rebasevector_celem_node(branch(0))) { - rbvec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + rbvec_node_ptr_ = static_cast*>(branch(0)); } } @@ -10936,10 +10940,10 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); T& v = rbvec_node_ptr_->ref(); - v = Operation::process(v,binary_node::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10963,15 +10967,17 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + assignment_vec_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) : binary_node(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_node(binary_node::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + vec_node_ptr_ = static_cast*>(branch(0)); vds() = vec_node_ptr_->vds(); } } @@ -10980,9 +10986,9 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node::branch_[1].first); + assert(branch(1)); - const T v = binary_node::branch_[1].first->value(); + const T v = branch(1)->value(); T* vec = vds().data(); @@ -11088,6 +11094,8 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + assignment_vecvec_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11096,22 +11104,22 @@ namespace exprtk , vec1_node_ptr_(0) , initialised_(false) { - if (is_vector_node(binary_node::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast*>(binary_node::branch_[0].first); + vec0_node_ptr_ = static_cast*>(branch(0)); vds() = vec0_node_ptr_->vds(); } - if (is_vector_node(binary_node::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast*>(binary_node::branch_[1].first); + vec1_node_ptr_ = static_cast*>(branch(1)); vec1_node_ptr_->vds() = vds(); } - else if (is_ivector_node(binary_node::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[1].first))) + if (0 != (vi = dynamic_cast*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); vec1_node_ptr_->vds() = vds(); @@ -11129,11 +11137,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); T* vec0 = vec0_node_ptr_->vds().data(); const T* vec1 = vec1_node_ptr_->vds().data(); @@ -11246,6 +11254,8 @@ namespace exprtk typedef vector_holder* vector_holder_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + vec_binop_vecvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11259,30 +11269,30 @@ namespace exprtk bool v0_is_ivec = false; bool v1_is_ivec = false; - if (is_vector_node(binary_node::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast(binary_node::branch_[0].first); + vec0_node_ptr_ = static_cast(branch(0)); } - else if (is_ivector_node(binary_node::branch_[0].first)) + else if (is_ivector_node(branch(0))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[0].first))) + if (0 != (vi = dynamic_cast*>(branch(0)))) { vec0_node_ptr_ = vi->vec(); v0_is_ivec = true; } } - if (is_vector_node(binary_node::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast(binary_node::branch_[1].first); + vec1_node_ptr_ = static_cast(branch(1)); } - else if (is_ivector_node(binary_node::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[1].first))) + if (0 != (vi = dynamic_cast*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); v1_is_ivec = true; @@ -11320,11 +11330,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); const T* vec0 = vec0_node_ptr_->vds().data(); const T* vec1 = vec1_node_ptr_->vds().data(); @@ -11436,6 +11446,8 @@ namespace exprtk typedef vector_holder* vector_holder_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + vec_binop_vecval_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11446,15 +11458,15 @@ namespace exprtk { bool v0_is_ivec = false; - if (is_vector_node(binary_node::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast(binary_node::branch_[0].first); + vec0_node_ptr_ = static_cast(branch(0)); } - else if (is_ivector_node(binary_node::branch_[0].first)) + else if (is_ivector_node(branch(0))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[0].first))) + if (0 != (vi = dynamic_cast*>(branch(0)))) { vec0_node_ptr_ = vi->vec(); v0_is_ivec = true; @@ -11483,11 +11495,11 @@ namespace exprtk { if (vec0_node_ptr_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node::branch_[0].first->value(); - const T v = binary_node::branch_[1].first->value(); + branch(0)->value(); + const T v = branch(1)->value(); const T* vec0 = vec0_node_ptr_->vds().data(); T* vec1 = vds().data(); @@ -11595,6 +11607,8 @@ namespace exprtk typedef vector_holder* vector_holder_ptr; typedef vec_data_store vds_t; + using binary_node::branch; + vec_binop_valvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11605,15 +11619,15 @@ namespace exprtk { bool v1_is_ivec = false; - if (is_vector_node(binary_node::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast(binary_node::branch_[1].first); + vec1_node_ptr_ = static_cast(branch(1)); } - else if (is_ivector_node(binary_node::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(binary_node::branch_[1].first))) + if (0 != (vi = dynamic_cast*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); v1_is_ivec = true; @@ -11642,11 +11656,11 @@ namespace exprtk { if (vec1_node_ptr_) { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - const T v = binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + const T v = branch(0)->value(); + branch(1)->value(); T* vec0 = vds().data(); const T* vec1 = vec1_node_ptr_->vds().data(); @@ -11754,6 +11768,8 @@ namespace exprtk typedef vector_holder* vector_holder_ptr; typedef vec_data_store vds_t; + using expression_node::branch; + unary_vector_node(const operator_type& opr, expression_ptr branch0) : unary_node(opr, branch0) , vec0_node_ptr_(0) @@ -11762,15 +11778,15 @@ namespace exprtk { bool vec0_is_ivec = false; - if (is_vector_node(unary_node::branch_.first)) + if (is_vector_node(branch())) { - vec0_node_ptr_ = static_cast(unary_node::branch_.first); + vec0_node_ptr_ = static_cast(branch()); } - else if (is_ivector_node(unary_node::branch_.first)) + else if (is_ivector_node(branch())) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(unary_node::branch_.first))) + if (0 != (vi = dynamic_cast*>(branch()))) { vec0_node_ptr_ = vi->vec(); vec0_is_ivec = true; @@ -11797,9 +11813,9 @@ namespace exprtk inline T value() const exprtk_override { - assert(unary_node::branch_.first); + assert(branch()); - unary_node::branch_.first->value(); + branch()->value(); if (vec0_node_ptr_) { @@ -12063,6 +12079,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; scand_node(const operator_type& opr, expression_ptr branch0, @@ -12072,14 +12089,14 @@ namespace exprtk inline T value() const exprtk_override { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); return ( std::not_equal_to() - (T(0),binary_node::branch_[0].first->value()) && + (T(0),branch(0)->value()) && std::not_equal_to() - (T(0),binary_node::branch_[1].first->value()) + (T(0),branch(1)->value()) ) ? T(1) : T(0); } }; @@ -12090,6 +12107,7 @@ namespace exprtk public: typedef expression_node* expression_ptr; + using binary_node::branch; scor_node(const operator_type& opr, expression_ptr branch0, @@ -12099,14 +12117,14 @@ namespace exprtk inline T value() const exprtk_override { - assert(binary_node::branch_[0].first); - assert(binary_node::branch_[1].first); + assert(branch(0)); + assert(branch(1)); return ( std::not_equal_to() - (T(0),binary_node::branch_[0].first->value()) || + (T(0),branch(0)->value()) || std::not_equal_to() - (T(0),binary_node::branch_[1].first->value()) + (T(0),branch(1)->value()) ) ? T(1) : T(0); } }; @@ -13533,7 +13551,7 @@ namespace exprtk case 3 : return process_3(arg_list); case 4 : return process_4(arg_list); case 5 : return process_5(arg_list); - default : return vararg_add_op::process(arg_list) / arg_list.size(); + default : return vararg_add_op::process(arg_list) / T(arg_list.size()); } } @@ -14192,8 +14210,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { - const std::size_t vec_size = v->vec()->vds().size(); - + const T vec_size = T(v->vec()->vds().size()); return vec_add_op::process(v) / vec_size; } }; @@ -16122,6 +16139,8 @@ namespace exprtk typedef range_interface irange_t; typedef irange_t* irange_ptr; + using binary_node::branch; + str_sogens_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -16131,14 +16150,14 @@ namespace exprtk , str0_range_ptr_(0) , str1_range_ptr_(0) { - if (is_generally_string_node(binary_node::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); + str0_base_ptr_ = dynamic_cast(branch(0)); if (0 == str0_base_ptr_) return; - irange_ptr range = dynamic_cast(binary_node::branch_[0].first); + irange_ptr range = dynamic_cast(branch(0)); if (0 == range) return; @@ -16146,14 +16165,14 @@ namespace exprtk str0_range_ptr_ = &(range->range_ref()); } - if (is_generally_string_node(binary_node::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); + str1_base_ptr_ = dynamic_cast(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast(binary_node::branch_[1].first); + irange_ptr range = dynamic_cast(branch(1)); if (0 == range) return; @@ -16171,8 +16190,8 @@ namespace exprtk str1_range_ptr_ ) { - binary_node::branch_[0].first->value(); - binary_node::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t str0_r0 = 0; std::size_t str0_r1 = 0; @@ -17292,22 +17311,29 @@ namespace exprtk { public: - typedef T (*ff00_functor)(); - typedef T (*ff01_functor)(T); - typedef T (*ff02_functor)(T, T); - typedef T (*ff03_functor)(T, T, T); - typedef T (*ff04_functor)(T, T, T, T); - typedef T (*ff05_functor)(T, T, T, T, T); - typedef T (*ff06_functor)(T, T, T, T, T, T); - typedef T (*ff07_functor)(T, T, T, T, T, T, T); - typedef T (*ff08_functor)(T, T, T, T, T, T, T, T); - typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T); - typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T); - typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T); + enum symtab_mutability_type + { + e_unknown = 0, + e_mutable = 1, + e_immutable = 2 + }; + + typedef T (*ff00_functor)(); + typedef T (*ff01_functor)(T); + typedef T (*ff02_functor)(T, T); + typedef T (*ff03_functor)(T, T, T); + typedef T (*ff04_functor)(T, T, T, T); + typedef T (*ff05_functor)(T, T, T, T, T); + typedef T (*ff06_functor)(T, T, T, T, T, T); + typedef T (*ff07_functor)(T, T, T, T, T, T, T); + typedef T (*ff08_functor)(T, T, T, T, T, T, T, T); + typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T); + typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T); + typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T); protected: @@ -17949,11 +17975,13 @@ namespace exprtk control_block() : ref_count(1) , data_(st_data::create()) + , mutability_(e_mutable) {} explicit control_block(st_data* data) : ref_count(1) , data_(data) + , mutability_(e_mutable) {} ~control_block() @@ -17989,21 +18017,29 @@ namespace exprtk } } + void set_mutability(const symtab_mutability_type mutability) + { + mutability_ = mutability; + } + std::size_t ref_count; st_data* data_; + symtab_mutability_type mutability_; }; public: - symbol_table() + symbol_table(const symtab_mutability_type mutability = e_mutable) : control_block_(control_block::create()) { + control_block_->set_mutability(mutability); clear(); } ~symbol_table() { - control_block::destroy(control_block_,this); + exprtk::details::dump_ptr("~symbol_table", this); + control_block::destroy(control_block_, this); } symbol_table(const symbol_table& st) @@ -18030,6 +18066,11 @@ namespace exprtk return (this == &st) || (control_block_ == st.control_block_); } + inline symtab_mutability_type mutability() const + { + return valid() ? control_block_->mutability_ : e_unknown; + } + inline void clear_variables(const bool delete_node = true) { local_data().variable_store.clear(delete_node); @@ -19103,6 +19144,7 @@ namespace exprtk inline expression& release() { + exprtk::details::dump_ptr("expression::release", this); control_block::destroy(control_block_); return (*this); @@ -19138,6 +19180,14 @@ namespace exprtk inline void register_symbol_table(symbol_table& st) { + for (std::size_t i = 0; i < symbol_table_list_.size(); ++i) + { + if (&st == &symbol_table_list_[i]) + { + return; + } + } + symbol_table_list_.push_back(st); } @@ -19905,6 +19955,130 @@ namespace exprtk parser_t& parser_; }; + template + struct halfopen_range_policy + { + static inline bool is_within(const T_& v, const T_& begin, const T_& end) + { + assert(begin <= end); + return (begin <= v) && (v < end); + } + + static inline bool is_less(const T_& v, const T_& begin) + { + return (v < begin); + } + + static inline bool is_greater(const T_& v, const T_& end) + { + return (end <= v); + } + + static inline bool end_inclusive() + { + return false; + } + }; + + template + struct closed_range_policy + { + static inline bool is_within(const T_& v, const T_& begin, const T_& end) + { + assert(begin <= end); + return (begin <= v) && (v <= end); + } + + static inline bool is_less(const T_& v, const T_& begin) + { + return (v < begin); + } + + static inline bool is_greater(const T_& v, const T_& end) + { + return (end < v); + } + + static inline bool end_inclusive() + { + return true; + } + }; + + template > + class interval_container_t + { + public: + + typedef IntervalPointType interval_point_t; + typedef std::pair interval_t; + typedef std::map interval_map_t; + typedef typename interval_map_t::const_iterator interval_map_citr_t; + + std::size_t size() const + { + return interval_map_.size(); + } + + void reset() + { + interval_map_.clear(); + } + + bool in_interval(const interval_point_t point, interval_t& interval) const + { + interval_map_citr_t itr = RangePolicy::end_inclusive() ? + interval_map_.lower_bound(point): + interval_map_.upper_bound(point); + + for (; itr != interval_map_.end(); ++itr) + { + const interval_point_t& begin = itr->second.first; + const interval_point_t& end = itr->second.second; + + if (RangePolicy::is_within(point, begin, end)) + { + interval = interval_t(begin,end); + return true; + } + else if (RangePolicy::is_greater(point, end)) + { + break; + } + } + + return false; + } + + bool in_interval(const interval_point_t point) const + { + interval_t interval; + return in_interval(point,interval); + } + + bool add_interval(const interval_point_t begin, const interval_point_t end) + { + if ((end <= begin) || in_interval(begin) || in_interval(end)) + { + return false; + } + + interval_map_[end] = std::make_pair(begin, end); + + return true; + } + + bool add_interval(const interval_t interval) + { + return add_interval(interval.first, interval.second); + } + + private: + + interval_map_t interval_map_; + }; + class stack_limit_handler { public: @@ -19959,6 +20133,41 @@ namespace exprtk typedef typename symbol_table_t::vararg_function_ptr vararg_function_ptr; typedef typename symbol_table_t::generic_function_ptr generic_function_ptr; + struct variable_context + { + variable_context() + : symbol_table(0) + , variable(0) + {} + + const symbol_table_t* symbol_table; + variable_ptr variable; + }; + + struct vector_context + { + vector_context() + : symbol_table(0) + , vector_holder(0) + {} + + const symbol_table_t* symbol_table; + vector_holder_ptr vector_holder; + }; + + #ifndef exprtk_disable_string_capabilities + struct string_context + { + string_context() + : symbol_table(0) + , str_var(0) + {} + + const symbol_table_t* symbol_table; + stringvar_ptr str_var; + }; + #endif + inline bool empty() const { return symtab_list_.empty(); @@ -19999,6 +20208,31 @@ namespace exprtk return false; } + inline variable_context get_variable_context(const std::string& variable_name) const + { + variable_context result; + if (!valid_symbol(variable_name)) + return result; + + for (std::size_t i = 0; i < symtab_list_.size(); ++i) + { + if (!symtab_list_[i].valid()) + { + continue; + } + + result.variable = local_data(i) + .variable_store.get(variable_name); + if (result.variable) + { + result.symbol_table = &symtab_list_[i]; + break; + } + } + + return result; + } + inline variable_ptr get_variable(const std::string& variable_name) const { if (!valid_symbol(variable_name)) @@ -20039,6 +20273,32 @@ namespace exprtk } #ifndef exprtk_disable_string_capabilities + inline string_context get_string_context(const std::string& string_name) const + { + string_context result; + + if (!valid_symbol(string_name)) + return result; + + for (std::size_t i = 0; i < symtab_list_.size(); ++i) + { + if (!symtab_list_[i].valid()) + { + continue; + } + + result.str_var = local_data(i).stringvar_store.get(string_name); + + if (result.str_var) + { + result.symbol_table = &symtab_list_[i]; + break; + } + } + + return result; + } + inline stringvar_ptr get_stringvar(const std::string& string_name) const { if (!valid_symbol(string_name)) @@ -20166,6 +20426,31 @@ namespace exprtk return result; } + inline vector_context get_vector_context(const std::string& vector_name) const + { + vector_context result; + if (!valid_symbol(vector_name)) + return result; + + for (std::size_t i = 0; i < symtab_list_.size(); ++i) + { + if (!symtab_list_[i].valid()) + { + continue; + } + + result.vector_holder = local_data(i).vector_store.get(vector_name); + + if (result.vector_holder) + { + result.symbol_table = &symtab_list_[i]; + break; + } + } + + return result; + } + inline vector_holder_ptr get_vector(const std::string& vector_name) const { if (!valid_symbol(vector_name)) @@ -23215,6 +23500,12 @@ namespace exprtk return parse_base_operation(); } + void handle_brkcnt_scope_exit() + { + assert(!brkcnt_list_.empty()); + brkcnt_list_.pop_front(); + } + inline expression_node_ptr parse_while_loop() { // Parse: [while][(][test expr][)][{][expression][}] @@ -23263,7 +23554,7 @@ namespace exprtk { scoped_inc_dec sid(state_.parsing_loop_stmt_count); - if (0 == (branch = parse_multi_sequence("while-loop"))) + if (0 == (branch = parse_multi_sequence("while-loop", true))) { set_error( make_error(parser_error::e_syntax, @@ -23285,18 +23576,18 @@ namespace exprtk } } + handle_brkcnt_scope_exit(); + if (!result) { free_node(node_allocator_, branch ); free_node(node_allocator_, condition ); free_node(node_allocator_, result_node); - brkcnt_list_.pop_front(); - return error_node(); } - else - return result_node; + + return result_node; } inline expression_node_ptr parse_repeat_until_loop() @@ -23375,8 +23666,6 @@ namespace exprtk if (sdd.delete_ptr) { - brkcnt_list_.pop_front(); - set_error( make_error(parser_error::e_syntax, current_token(), @@ -23389,8 +23678,6 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - brkcnt_list_.pop_front(); - set_error( make_error(parser_error::e_syntax, current_token(), @@ -23398,13 +23685,10 @@ namespace exprtk exprtk_error_location)); free_node(node_allocator_,branch); - return error_node(); } else if (0 == (condition = parse_expression())) { - brkcnt_list_.pop_front(); - set_error( make_error(parser_error::e_syntax, current_token(), @@ -23412,7 +23696,6 @@ namespace exprtk exprtk_error_location)); free_node(node_allocator_,branch); - return error_node(); } else if (!token_is(token_t::e_rbracket)) @@ -23426,8 +23709,6 @@ namespace exprtk free_node(node_allocator_, branch ); free_node(node_allocator_, condition); - brkcnt_list_.pop_front(); - return error_node(); } @@ -23446,15 +23727,12 @@ namespace exprtk free_node(node_allocator_,condition); - brkcnt_list_.pop_front(); - return error_node(); } - else - { - brkcnt_list_.pop_front(); - return result; - } + + handle_brkcnt_scope_exit(); + + return result; } inline expression_node_ptr parse_for_loop() @@ -23646,7 +23924,7 @@ namespace exprtk scoped_inc_dec sid(state_.parsing_loop_stmt_count); - if (0 == (loop_body = parse_multi_sequence("for-loop"))) + if (0 == (loop_body = parse_multi_sequence("for-loop", true))) { set_error( make_error(parser_error::e_syntax, @@ -23669,26 +23947,18 @@ namespace exprtk free_node(node_allocator_, condition ); free_node(node_allocator_, incrementor); free_node(node_allocator_, loop_body ); - - if (!brkcnt_list_.empty()) - { - brkcnt_list_.pop_front(); - } - return error_node(); } - else - { - expression_node_ptr result_node = - expression_generator_.for_loop(initialiser, - condition, - incrementor, - loop_body, - brkcnt_list_.front()); - brkcnt_list_.pop_front(); - return result_node; - } + expression_node_ptr result_node = + expression_generator_.for_loop(initialiser, + condition, + incrementor, + loop_body, + brkcnt_list_.front()); + handle_brkcnt_scope_exit(); + + return result_node; } inline expression_node_ptr parse_switch_statement() @@ -23998,7 +24268,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR096 - Unsupported vararg function: " + symbol, + "ERR096 - Unsupported built-in vararg function: " + symbol, exprtk_error_location)); return error_node(); @@ -24021,6 +24291,18 @@ namespace exprtk return error_node(); } + if (token_is(token_t::e_rbracket)) + { + set_error( + make_error(parser_error::e_syntax, + current_token(), + "ERR098 - vararg function: " + symbol + + " requires at least one input parameter", + exprtk_error_location)); + + return error_node(); + } + for ( ; ; ) { expression_node_ptr arg = parse_expression(); @@ -24037,7 +24319,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR098 - Expected ',' for call to vararg function: " + symbol, + "ERR099 - Expected ',' for call to vararg function: " + symbol, exprtk_error_location)); return error_node(); @@ -24058,7 +24340,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR099 - Expected '[' as start of string range definition", + "ERR100 - Expected '[' as start of string range definition", exprtk_error_location)); free_node(node_allocator_,expression); @@ -24086,7 +24368,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR100 - Failed to generate string range node", + "ERR101 - Failed to generate string range node", exprtk_error_location)); free_node(node_allocator_,expression); @@ -24206,15 +24488,18 @@ namespace exprtk return expression_generator_.vararg_function(details::e_multi,expression_list); } - inline expression_node_ptr parse_multi_sequence(const std::string& source = "") + inline expression_node_ptr parse_multi_sequence(const std::string& source = "", + const bool enforce_crlbrackets = false) { + token_t::token_type open_bracket = token_t::e_lcrlbracket; token_t::token_type close_bracket = token_t::e_rcrlbracket; token_t::token_type seperator = token_t::e_eof; - if (!token_is(token_t::e_lcrlbracket)) + if (!token_is(open_bracket)) { - if (token_is(token_t::e_lbracket)) + if (!enforce_crlbrackets && token_is(token_t::e_lbracket)) { + open_bracket = token_t::e_lbracket; close_bracket = token_t::e_rbracket; seperator = token_t::e_comma; } @@ -24223,14 +24508,14 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR101 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" + + "ERR102 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" + ((!source.empty()) ? std::string(" section of " + source): ""), exprtk_error_location)); return error_node(); } } - else if (token_is(token_t::e_rcrlbracket)) + else if (token_is(close_bracket)) { return node_allocator_.allocate >(); } @@ -24270,7 +24555,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR102 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source, + "ERR103 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source, exprtk_error_location)); return error_node(); @@ -24280,7 +24565,7 @@ namespace exprtk break; } - result = simplify(arg_list,side_effect_list,source.empty()); + result = simplify(arg_list, side_effect_list, source.empty()); sdd.delete_ptr = (0 == result); return result; @@ -24304,7 +24589,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR103 - Expected '[' for start of range", + "ERR104 - Expected '[' for start of range", exprtk_error_location)); return false; @@ -24325,7 +24610,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR104 - Failed parse begin section of range", + "ERR105 - Failed parse begin section of range", exprtk_error_location)); return false; @@ -24348,7 +24633,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR105 - Range lower bound less than zero! Constraint: r0 >= 0", + "ERR106 - Range lower bound less than zero! Constraint: r0 >= 0", exprtk_error_location)); return false; @@ -24365,7 +24650,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR106 - Expected ':' for break in range", + "ERR107 - Expected ':' for break in range", exprtk_error_location)); rp.free(); @@ -24388,7 +24673,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR107 - Failed parse end section of range", + "ERR108 - Failed parse end section of range", exprtk_error_location)); rp.free(); @@ -24413,7 +24698,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR108 - Range upper bound less than zero! Constraint: r1 >= 0", + "ERR109 - Range upper bound less than zero! Constraint: r1 >= 0", exprtk_error_location)); rp.free(); @@ -24432,7 +24717,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR109 - Expected ']' for start of range", + "ERR110 - Expected ']' for start of range", exprtk_error_location)); rp.free(); @@ -24460,7 +24745,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR110 - Invalid range, Constraint: r0 <= r1", + "ERR111 - Invalid range, Constraint: r0 <= r1", exprtk_error_location)); return false; @@ -24496,24 +24781,36 @@ namespace exprtk } else { - if (!symtab_store_.is_conststr_stringvar(symbol)) + typedef typename symtab_store::string_context str_ctxt_t; + str_ctxt_t str_ctx = symtab_store_.get_string_context(symbol); + + if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol)) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR111 - Unknown string symbol", + "ERR112 - Unknown string symbol", exprtk_error_location)); return error_node(); } - result = symtab_store_.get_stringvar(symbol); + assert(str_ctx.str_var != 0); + assert(str_ctx.symbol_table != 0); + + result = str_ctx.str_var; if (symtab_store_.is_constant_string(symbol)) { const_str_node = static_cast(result); result = expression_generator_(const_str_node->str()); } + else if (symbol_table_t::e_immutable == str_ctx.symbol_table->mutability()) + { + lodge_immutable_symbol( + current_token(), + make_memory_range(str_ctx.str_var->base(), str_ctx.str_var->size())); + } lodge_symbol(symbol, e_st_string); } @@ -24616,7 +24913,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR112 - Overflow in range for string: '" + const_str + "'[" + + "ERR113 - Overflow in range for string: '" + const_str + "'[" + (rp.n0_c.first ? details::to_str(static_cast(rp.n0_c.second)) : "?") + ":" + (rp.n1_c.first ? details::to_str(static_cast(rp.n1_c.second)) : "?") + "]", exprtk_error_location)); @@ -24657,20 +24954,37 @@ namespace exprtk (scope_element::e_vector != se.type) ) { - if (0 == (vec = symtab_store_.get_vector(symbol))) + typedef typename symtab_store::vector_context vec_ctxt_t; + vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(symbol); + + if (0 == vec_ctx.vector_holder) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR113 - Symbol '" + symbol+ " not a vector", + "ERR114 - Symbol '" + symbol+ " not a vector", exprtk_error_location)); return error_node(); } + + assert(0 != vec_ctx.vector_holder); + assert(0 != vec_ctx.symbol_table ); + + vec = vec_ctx.vector_holder; + + if (symbol_table_t::e_immutable == vec_ctx.symbol_table->mutability()) + { + lodge_immutable_symbol( + current_token(), + make_memory_range(vec->data(), vec->size())); + } } else vec = se.vec_node; + assert(0 != vec); + expression_node_ptr index_expr = error_node(); next_token(); @@ -24688,7 +25002,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR114 - Failed to parse index for vector: '" + symbol + "'", + "ERR115 - Failed to parse index for vector: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -24698,7 +25012,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR115 - Expected ']' for index of vector: '" + symbol + "'", + "ERR116 - Expected ']' for index of vector: '" + symbol + "'", exprtk_error_location)); free_node(node_allocator_,index_expr); @@ -24717,7 +25031,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR116 - Index of " + details::to_str(index) + " out of range for " + "ERR117 - Index of " + details::to_str(index) + " out of range for " "vector '" + symbol + "' of size " + details::to_str(vec_size), exprtk_error_location)); @@ -24749,7 +25063,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR117 - Zero parameter call to vararg function: " + "ERR118 - Zero parameter call to vararg function: " + vararg_function_name + " not allowed", exprtk_error_location)); @@ -24774,7 +25088,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR118 - Expected ',' for call to vararg function: " + "ERR119 - Expected ',' for call to vararg function: " + vararg_function_name, exprtk_error_location)); @@ -24788,7 +25102,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR119 - Zero parameter call to vararg function: " + "ERR120 - Zero parameter call to vararg function: " + vararg_function_name + " not allowed", exprtk_error_location)); @@ -24800,7 +25114,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR120 - Invalid number of parameters to call to vararg function: " + "ERR121 - Invalid number of parameters to call to vararg function: " + vararg_function_name + ", require at least " + details::to_str(static_cast(vararg_function->min_num_args())) + " parameters", exprtk_error_location)); @@ -24812,7 +25126,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR121 - Invalid number of parameters to call to vararg function: " + "ERR122 - Invalid number of parameters to call to vararg function: " + vararg_function_name + ", require no more than " + details::to_str(static_cast(vararg_function->max_num_args())) + " parameters", exprtk_error_location)); @@ -24890,7 +25204,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR122 - Failed parameter type check for function '" + function_name_ + "', " + "ERR123 - Failed parameter type check for function '" + function_name_ + "', " "Expected '" + function_definition_list_[0].param_seq + "' call set: '" + param_seq + "'", exprtk_error_location)); @@ -24912,7 +25226,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR123 - Failed parameter type check for function '" + function_name_ + "', " + "ERR124 - Failed parameter type check for function '" + function_name_ + "', " "Best match: '" + function_definition_list_[max_diff_index].param_seq + "' call set: '" + param_seq + "'", exprtk_error_location)); @@ -25054,7 +25368,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR124 - Invalid parameter sequence of '" + param_seq_list[i] + + "ERR125 - Invalid parameter sequence of '" + param_seq_list[i] + "' for function: " + function_name_, exprtk_error_location)); return; @@ -25070,7 +25384,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR125 - Function '" + function_name_ + "' has a parameter sequence conflict between " + + "ERR126 - Function '" + function_name_ + "' has a parameter sequence conflict between " + "pseq_idx[" + details::to_str(seq_itr->second) + "] and" + "pseq_idx[" + details::to_str(i) + "] " + "param seq: " + param_seq_list[i], @@ -25102,14 +25416,18 @@ namespace exprtk std::string param_type_list; - type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string); + type_checker tc( + (*this), + function_name, + function->parameter_sequence, + type_checker::e_string); if (tc.invalid()) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR126 - Type checker instantiation failure for generic function: " + function_name, + "ERR127 - Type checker instantiation failure for generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -25127,7 +25445,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR127 - Zero parameter call to generic function: " + "ERR128 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -25159,7 +25477,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR128 - Expected ',' for call to generic function: " + function_name, + "ERR129 - Expected ',' for call to generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -25176,7 +25494,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR129 - Zero parameter call to generic function: " + "ERR130 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -25193,7 +25511,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR130 - Invalid input parameter sequence for call to generic function: " + function_name, + "ERR131 - Invalid input parameter sequence for call to generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -25231,7 +25549,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR131 - Zero parameter call to generic function: " + "ERR132 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -25263,7 +25581,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR132 - Expected ',' for call to string function: " + function_name, + "ERR133 - Expected ',' for call to string function: " + function_name, exprtk_error_location)); return false; @@ -25310,7 +25628,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR133 - Invalid input parameter sequence for call to string function: " + function_name, + "ERR134 - Invalid input parameter sequence for call to string function: " + function_name, exprtk_error_location)); return error_node(); @@ -25362,7 +25680,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR134 - Invalid input parameter sequence for call to overloaded function: " + function_name, + "ERR135 - Invalid input parameter sequence for call to overloaded function: " + function_name, exprtk_error_location)); return error_node(); @@ -25393,7 +25711,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR135 - Invalid return type for call to overloaded function: " + function_name, + "ERR136 - Invalid return type for call to overloaded function: " + function_name, exprtk_error_location)); } @@ -25421,7 +25739,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR136 - Expected '(' for special function '" + sf_name + "'", + "ERR137 - Expected '(' for special function '" + sf_name + "'", exprtk_error_location)); return error_node(); @@ -25442,7 +25760,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR137 - Expected ',' before next parameter of special function '" + sf_name + "'", + "ERR138 - Expected ',' before next parameter of special function '" + sf_name + "'", exprtk_error_location)); return p.error_node(); @@ -25455,7 +25773,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR138 - Invalid number of parameters for special function '" + sf_name + "'", + "ERR139 - Invalid number of parameters for special function '" + sf_name + "'", exprtk_error_location)); return p.error_node(); @@ -25482,7 +25800,7 @@ namespace exprtk set_error( make_error(parser_error::e_token, current_token(), - "ERR139 - Invalid special function[1]: " + sf_name, + "ERR140 - Invalid special function[1]: " + sf_name, exprtk_error_location)); return error_node(); @@ -25496,7 +25814,7 @@ namespace exprtk set_error( make_error(parser_error::e_token, current_token(), - "ERR140 - Invalid special function[2]: " + sf_name, + "ERR141 - Invalid special function[2]: " + sf_name, exprtk_error_location)); return error_node(); @@ -25528,7 +25846,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR141 - Invoking 'break' within a break call is not allowed", + "ERR142 - Invoking 'break' within a break call is not allowed", exprtk_error_location)); return error_node(); @@ -25538,7 +25856,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR142 - Invalid use of 'break', allowed only in the scope of a loop", + "ERR143 - Invalid use of 'break', allowed only in the scope of a loop", exprtk_error_location)); return error_node(); @@ -25561,7 +25879,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR143 - Failed to parse return expression for 'break' statement", + "ERR144 - Failed to parse return expression for 'break' statement", exprtk_error_location)); return error_node(); @@ -25571,7 +25889,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR144 - Expected ']' at the completion of break's return expression", + "ERR145 - Expected ']' at the completion of break's return expression", exprtk_error_location)); free_node(node_allocator_,return_expr); @@ -25589,7 +25907,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR145 - Invalid use of 'break', allowed only in the scope of a loop", + "ERR146 - Invalid use of 'break', allowed only in the scope of a loop", exprtk_error_location)); } @@ -25603,7 +25921,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR146 - Invalid use of 'continue', allowed only in the scope of a loop", + "ERR147 - Invalid use of 'continue', allowed only in the scope of a loop", exprtk_error_location)); return error_node(); @@ -25629,7 +25947,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR147 - Expected '[' as part of vector size definition", + "ERR148 - Expected '[' as part of vector size definition", exprtk_error_location)); return error_node(); @@ -25639,7 +25957,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR148 - Failed to determine size of vector '" + vec_name + "'", + "ERR149 - Failed to determine size of vector '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25651,7 +25969,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR149 - Expected a literal number as size of vector '" + vec_name + "'", + "ERR150 - Expected a literal number as size of vector '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25673,7 +25991,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR150 - Invalid vector size. Must be an integer in the range [0,2e9], size: " + + "ERR151 - Invalid vector size. Must be an integer in the range [0,2e9], size: " + details::to_str(details::numeric::to_int32(vector_size)), exprtk_error_location)); @@ -25693,7 +26011,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR151 - Expected ']' as part of vector size definition", + "ERR152 - Expected ']' as part of vector size definition", exprtk_error_location)); return error_node(); @@ -25705,7 +26023,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR152 - Expected ':=' as part of vector definition", + "ERR153 - Expected ':=' as part of vector definition", exprtk_error_location)); return error_node(); @@ -25719,7 +26037,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR153 - Failed to parse single vector initialiser", + "ERR154 - Failed to parse single vector initialiser", exprtk_error_location)); return error_node(); @@ -25732,7 +26050,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR154 - Expected ']' to close single value vector initialiser", + "ERR155 - Expected ']' to close single value vector initialiser", exprtk_error_location)); return error_node(); @@ -25779,7 +26097,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR155 - Expected '{' as part of vector initialiser list", + "ERR156 - Expected '{' as part of vector initialiser list", exprtk_error_location)); return error_node(); @@ -25799,7 +26117,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR156 - Expected '{' as part of vector initialiser list", + "ERR157 - Expected '{' as part of vector initialiser list", exprtk_error_location)); return error_node(); @@ -25817,7 +26135,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR157 - Expected ',' between vector initialisers", + "ERR158 - Expected ',' between vector initialisers", exprtk_error_location)); return error_node(); @@ -25839,19 +26157,19 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR158 - Expected ';' at end of vector definition", + "ERR159 - Expected ';' at end of vector definition", exprtk_error_location)); return error_node(); } } - if (vec_initilizer_list.size() > vector_size) + if (T(vec_initilizer_list.size()) > vector_size) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR159 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", + "ERR160 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25871,7 +26189,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR160 - Illegal redefinition of local vector: '" + vec_name + "'", + "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25905,7 +26223,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR161 - Failed to add new local vector '" + vec_name + "' to SEM", + "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM", exprtk_error_location)); sem_.free_element(nse); @@ -25964,7 +26282,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR162 - Illegal redefinition of local variable: '" + str_name + "'", + "ERR163 - Illegal redefinition of local variable: '" + str_name + "'", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -25996,7 +26314,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR163 - Failed to add new local string variable '" + str_name + "' to SEM", + "ERR164 - Failed to add new local string variable '" + str_name + "' to SEM", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -26042,7 +26360,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR164 - Illegal variable definition", + "ERR165 - Illegal variable definition", exprtk_error_location)); return error_node(); @@ -26063,7 +26381,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR165 - Expected a symbol for variable definition", + "ERR166 - Expected a symbol for variable definition", exprtk_error_location)); return error_node(); @@ -26073,7 +26391,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR166 - Illegal redefinition of reserved keyword: '" + var_name + "'", + "ERR167 - Illegal redefinition of reserved keyword: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26083,7 +26401,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR167 - Illegal redefinition of variable '" + var_name + "'", + "ERR168 - Illegal redefinition of variable '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26093,7 +26411,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR168 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR169 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26113,7 +26431,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR169 - Failed to parse initialisation expression", + "ERR170 - Failed to parse initialisation expression", exprtk_error_location)); return error_node(); @@ -26131,7 +26449,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR170 - Expected ';' after variable definition", + "ERR171 - Expected ';' after variable definition", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -26159,7 +26477,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR171 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR172 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -26191,7 +26509,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR172 - Failed to add new local variable '" + var_name + "' to SEM", + "ERR173 - Failed to add new local variable '" + var_name + "' to SEM", exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -26228,7 +26546,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR173 - Expected a '{}' for uninitialised var definition", + "ERR174 - Expected a '{}' for uninitialised var definition", exprtk_error_location)); return error_node(); @@ -26238,7 +26556,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR174 - Expected ';' after uninitialised variable definition", + "ERR175 - Expected ';' after uninitialised variable definition", exprtk_error_location)); return error_node(); @@ -26255,7 +26573,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR175 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR176 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26285,7 +26603,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR176 - Failed to add new local variable '" + var_name + "' to SEM", + "ERR177 - Failed to add new local variable '" + var_name + "' to SEM", exprtk_error_location)); sem_.free_element(nse); @@ -26318,7 +26636,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR177 - Expected '(' at start of swap statement", + "ERR178 - Expected '(' at start of swap statement", exprtk_error_location)); return error_node(); @@ -26337,7 +26655,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR178 - Expected a symbol for variable or vector element definition", + "ERR179 - Expected a symbol for variable or vector element definition", exprtk_error_location)); return error_node(); @@ -26349,7 +26667,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR179 - First parameter to swap is an invalid vector element: '" + var0_name + "'", + "ERR180 - First parameter to swap is an invalid vector element: '" + var0_name + "'", exprtk_error_location)); return error_node(); @@ -26382,7 +26700,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR180 - First parameter to swap is an invalid variable: '" + var0_name + "'", + "ERR181 - First parameter to swap is an invalid variable: '" + var0_name + "'", exprtk_error_location)); return error_node(); @@ -26396,7 +26714,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR181 - Expected ',' between parameters to swap", + "ERR182 - Expected ',' between parameters to swap", exprtk_error_location)); if (variable0_generated) @@ -26414,7 +26732,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR182 - Expected a symbol for variable or vector element definition", + "ERR183 - Expected a symbol for variable or vector element definition", exprtk_error_location)); if (variable0_generated) @@ -26431,7 +26749,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR183 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", + "ERR184 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", exprtk_error_location)); if (variable0_generated) @@ -26469,7 +26787,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR184 - Second parameter to swap is an invalid variable: '" + var1_name + "'", + "ERR185 - Second parameter to swap is an invalid variable: '" + var1_name + "'", exprtk_error_location)); if (variable0_generated) @@ -26488,7 +26806,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR185 - Expected ')' at end of swap statement", + "ERR186 - Expected ')' at end of swap statement", exprtk_error_location)); if (variable0_generated) @@ -26545,7 +26863,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR186 - Return call within a return call is not allowed", + "ERR187 - Return call within a return call is not allowed", exprtk_error_location)); return error_node(); @@ -26569,7 +26887,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR187 - Expected '[' at start of return statement", + "ERR188 - Expected '[' at start of return statement", exprtk_error_location)); return error_node(); @@ -26592,7 +26910,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR188 - Expected ',' between values during call to return", + "ERR189 - Expected ',' between values during call to return", exprtk_error_location)); return error_node(); @@ -26604,7 +26922,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR189 - Zero parameter return statement not allowed", + "ERR190 - Zero parameter return statement not allowed", exprtk_error_location)); return error_node(); @@ -26619,7 +26937,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, prev_token, - "ERR190 - Invalid ']' found during return call", + "ERR191 - Invalid ']' found during return call", exprtk_error_location)); return error_node(); @@ -26672,7 +26990,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR191 - Invalid sequence of variable '"+ symbol + "' and bracket", + "ERR192 - Invalid sequence of variable '" + symbol + "' and bracket", exprtk_error_location)); return false; @@ -26720,7 +27038,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR192 - Invalid sequence of brackets", + "ERR193 - Invalid sequence of brackets", exprtk_error_location)); return false; @@ -26736,27 +27054,65 @@ namespace exprtk return true; } + typedef typename interval_container_t::interval_t interval_t; + typedef interval_container_t immutable_memory_map_t; + typedef std::map immutable_symtok_map_t; + + inline interval_t make_memory_range(const T& t) + { + const T* begin = reinterpret_cast(&t); + const T* end = begin + 1; + return interval_t(begin, end); + } + + inline interval_t make_memory_range(const T* begin, const std::size_t size) + { + return interval_t(begin, begin + size); + } + + inline interval_t make_memory_range(details::char_cptr begin, const std::size_t size) + { + return interval_t(begin, begin + size); + } + + void lodge_immutable_symbol(const lexer::token& token, const interval_t interval) + { + immutable_memory_map_.add_interval(interval); + immutable_symtok_map_[interval] = token; + } + inline expression_node_ptr parse_symtab_symbol() { const std::string symbol = current_token().value; // Are we dealing with a variable or a special constant? - expression_node_ptr variable = symtab_store_.get_variable(symbol); + typedef typename symtab_store::variable_context var_ctxt_t; + var_ctxt_t var_ctx = symtab_store_.get_variable_context(symbol); - if (variable) + if (var_ctx.variable) { + assert(var_ctx.symbol_table); + + expression_node_ptr result_variable = var_ctx.variable; + if (symtab_store_.is_constant_node(symbol)) { - variable = expression_generator_(variable->value()); + result_variable = expression_generator_(var_ctx.variable->value()); + } + else if (symbol_table_t::e_immutable == var_ctx.symbol_table->mutability()) + { + lodge_immutable_symbol(current_token(), make_memory_range(var_ctx.variable->ref())); + result_variable = var_ctx.variable; } if (!post_variable_process(symbol)) return error_node(); lodge_symbol(symbol, e_st_variable); + next_token(); - return variable; + return result_variable; } // Are we dealing with a locally defined variable, vector or string? @@ -26817,7 +27173,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR193 - Failed to generate node for function: '" + symbol + "'", + "ERR194 - Failed to generate node for function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26843,7 +27199,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR194 - Failed to generate node for vararg function: '" + symbol + "'", + "ERR195 - Failed to generate node for vararg function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26869,7 +27225,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR195 - Failed to generate node for generic function: '" + symbol + "'", + "ERR196 - Failed to generate node for generic function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26896,7 +27252,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR196 - Failed to generate node for string function: '" + symbol + "'", + "ERR197 - Failed to generate node for string function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26922,7 +27278,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR197 - Failed to generate node for overload function: '" + symbol + "'", + "ERR198 - Failed to generate node for overload function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26948,7 +27304,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR198 - Invalid use of reserved symbol '" + symbol + "'", + "ERR199 - Invalid use of reserved symbol '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -27011,7 +27367,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR199 - Failed to create variable: '" + symbol + "'" + + "ERR200 - Failed to create variable: '" + symbol + "'" + (error_message.empty() ? "" : " - " + error_message), exprtk_error_location)); @@ -27031,7 +27387,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR200 - Failed to resolve symbol: '" + symbol + "'" + + "ERR201 - Failed to resolve symbol: '" + symbol + "'" + (error_message.empty() ? "" : " - " + error_message), exprtk_error_location)); } @@ -27043,7 +27399,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR201 - Undefined symbol: '" + symbol + "'", + "ERR202 - Undefined symbol: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -27157,7 +27513,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR202 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol, + "ERR203 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol, exprtk_error_location)); return error_node(); @@ -27188,7 +27544,7 @@ namespace exprtk set_error( make_error(parser_error::e_numeric, current_token(), - "ERR203 - Failed generate node for scalar: '" + current_token().value + "'", + "ERR204 - Failed generate node for scalar: '" + current_token().value + "'", exprtk_error_location)); return error_node(); @@ -27202,7 +27558,7 @@ namespace exprtk set_error( make_error(parser_error::e_numeric, current_token(), - "ERR204 - Failed to convert '" + current_token().value + "' to a number", + "ERR205 - Failed to convert '" + current_token().value + "' to a number", exprtk_error_location)); return error_node(); @@ -27229,7 +27585,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR205 - Expected ')' instead of: '" + current_token().value + "'", + "ERR206 - Expected ')' instead of: '" + current_token().value + "'", exprtk_error_location)); details::free_node(node_allocator_,branch); @@ -27254,7 +27610,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR206 - Expected ']' instead of: '" + current_token().value + "'", + "ERR207 - Expected ']' instead of: '" + current_token().value + "'", exprtk_error_location)); details::free_node(node_allocator_,branch); @@ -27279,7 +27635,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR207 - Expected '}' instead of: '" + current_token().value + "'", + "ERR208 - Expected '}' instead of: '" + current_token().value + "'", exprtk_error_location)); details::free_node(node_allocator_,branch); @@ -27328,7 +27684,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR208 - Premature end of expression[1]", + "ERR209 - Premature end of expression[1]", exprtk_error_location)); return error_node(); @@ -27338,7 +27694,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR209 - Premature end of expression[2]", + "ERR210 - Premature end of expression[2]", exprtk_error_location)); return error_node(); @@ -29627,43 +29983,105 @@ namespace exprtk } } + const void* base_ptr(expression_node_ptr node) + { + if (node) + { + switch(node->type()) + { + case details::expression_node::e_variable: + return reinterpret_cast(&static_cast(node)->ref()); + + case details::expression_node::e_vecelem: + return reinterpret_cast(&static_cast(node)->ref()); + + case details::expression_node::e_rbvecelem: + return reinterpret_cast(&static_cast(node)->ref()); + + case details::expression_node::e_rbveccelem: + return reinterpret_cast(&static_cast(node)->ref()); + + case details::expression_node::e_vector: + return reinterpret_cast(static_cast(node)->vec_holder().data()); + + #ifndef exprtk_disable_string_capabilities + case details::expression_node::e_stringvar: + return reinterpret_cast((static_cast(node)->base())); + + case details::expression_node::e_stringvarrng: + return reinterpret_cast((static_cast(node)->base())); + #endif + default : return reinterpret_cast(0); + } + } + + return reinterpret_cast(0); + } + + bool assign_immutable_symbol(expression_node_ptr node) + { + interval_t interval; + const void* baseptr_addr = base_ptr(node); + + exprtk_debug(("assign_immutable_symbol - base ptr addr: %p\n", baseptr_addr)); + + if (parser_->immutable_memory_map_.in_interval(baseptr_addr,interval)) + { + typename immutable_symtok_map_t::iterator itr = parser_->immutable_symtok_map_.find(interval); + + if (parser_->immutable_symtok_map_.end() != itr) + { + token_t& token = itr->second; + parser_->set_error( + parser_error::make_error(parser_error::e_parser, + token, + "ERR211 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.", + exprtk_error_location)); + } + else + parser_->set_synthesis_error("Unable to assign symbol is immutable."); + + return true; + } + + return false; + } + inline expression_node_ptr synthesize_assignment_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) { - if (details::is_variable_node(branch[0])) + if (assign_immutable_symbol(branch[0])) + { + return error_node(); + } + else if (details::is_variable_node(branch[0])) { lodge_assignment(e_st_variable,branch[0]); - return synthesize_expression(operation,branch); } else if (details::is_vector_elem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); - return synthesize_expression(operation, branch); } else if (details::is_rebasevector_elem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); - return synthesize_expression(operation, branch); } else if (details::is_rebasevector_celem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); - return synthesize_expression(operation, branch); } #ifndef exprtk_disable_string_capabilities else if (details::is_string_node(branch[0])) { lodge_assignment(e_st_string,branch[0]); - return synthesize_expression(operation, branch); } else if (details::is_string_range_node(branch[0])) { lodge_assignment(e_st_string,branch[0]); - return synthesize_expression(operation, branch); } #endif @@ -29687,6 +30105,11 @@ namespace exprtk inline expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) { + if (assign_immutable_symbol(branch[0])) + { + return error_node(); + } + if (details::is_variable_node(branch[0])) { lodge_assignment(e_st_variable,branch[0]); @@ -37006,6 +37429,9 @@ namespace exprtk std::string synthesis_error_; scope_element_manager sem_; + immutable_memory_map_t immutable_memory_map_; + immutable_symtok_map_t immutable_symtok_map_; + lexer::helper::helper_assembly helper_assembly_; lexer::helper::commutative_inserter commutative_inserter_; @@ -38552,202 +38978,7 @@ namespace exprtk std::vector auxiliary_symtab_list_; }; // class function_compositor - template - inline bool pgo_primer() - { - static const std::string expression_list[] = - { - "(y + x)", - "2 * (y + x)", - "(2 * y + 2 * x)", - "(y + x / y) * (x - y / x)", - "x / ((x + y) * (x - y)) / y", - "1 - ((x * y) + (y / x)) - 3", - "sin(2 * x) + cos(pi / y)", - "1 - sin(2 * x) + cos(pi / y)", - "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)", - "(x^2 / sin(2 * pi / y)) -x / 2", - "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y", - "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)", - "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)", - "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))", - "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x", - "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55", - "(yy + xx)", - "2 * (yy + xx)", - "(2 * yy + 2 * xx)", - "(yy + xx / yy) * (xx - yy / xx)", - "xx / ((xx + yy) * (xx - yy)) / yy", - "1 - ((xx * yy) + (yy / xx)) - 3", - "sin(2 * xx) + cos(pi / yy)", - "1 - sin(2 * xx) + cos(pi / yy)", - "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)", - "(xx^2 / sin(2 * pi / yy)) -xx / 2", - "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy", - "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)", - "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))", - "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx", - "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55", - "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))", - "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)", - "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)", - "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)", - "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)", - "(x + 2) * 3", "x + (2 * 3)", - "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)", - "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)", - "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))", - "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))", - "2 + (x * (y / 3))", "x + (2 * (3 / y))", - "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)", - "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)", - "x + ((2 * 3) / y)", "(((x + y) * z) / w)", - "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)", - "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)", - "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)", - "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)", - "((x + (2 * 3)) / y)", - "(xx + yy) * zz", "xx + (yy * zz)", - "(xx + yy) * 7", "xx + (yy * 7)", - "(xx + 7) * yy", "xx + (7 * yy)", - "(7 + xx) * yy", "7 + (xx * yy)", - "(2 + x) * 3", "2 + (x * 3)", - "(2 + 3) * x", "2 + (3 * x)", - "(x + 2) * 3", "x + (2 * 3)", - "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)", - "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)", - "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)", - "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)", - "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))", - "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))", - "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))", - "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))", - "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))", - "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)", - "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)", - "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)", - "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)", - "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)", - "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)", - "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)", - "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)", - "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)", - "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)", - "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)", - "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)", - "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)", - "((xx + (2 * 3)) / yy)" - }; - - static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string); - - T x = T(0); - T y = T(0); - T z = T(0); - T w = T(0); - T xx = T(0); - T yy = T(0); - T zz = T(0); - T ww = T(0); - - exprtk::symbol_table symbol_table; - symbol_table.add_constants(); - symbol_table.add_variable( "x", x); - symbol_table.add_variable( "y", y); - symbol_table.add_variable( "z", z); - symbol_table.add_variable( "w", w); - symbol_table.add_variable("xx",xx); - symbol_table.add_variable("yy",yy); - symbol_table.add_variable("zz",zz); - symbol_table.add_variable("ww",ww); - - typedef typename std::deque > expr_list_t; - expr_list_t expr_list; - - const std::size_t rounds = 50; - - { - for (std::size_t r = 0; r < rounds; ++r) - { - expr_list.clear(); - exprtk::parser parser; - - for (std::size_t i = 0; i < expression_list_size; ++i) - { - exprtk::expression expression; - expression.register_symbol_table(symbol_table); - - if (!parser.compile(expression_list[i],expression)) - { - return false; - } - - expr_list.push_back(expression); - } - } - } - - struct execute - { - static inline T process(T& x, T& y, expression& expression) - { - static const T lower_bound = T(-20); - static const T upper_bound = T(+20); - static const T delta = T(0.1); - - T total = T(0); - - for (x = lower_bound; x <= upper_bound; x += delta) - { - for (y = lower_bound; y <= upper_bound; y += delta) - { - total += expression.value(); - } - } - - return total; - } - }; - - for (std::size_t i = 0; i < expr_list.size(); ++i) - { - execute::process( x, y, expr_list[i]); - execute::process(xx, yy, expr_list[i]); - } - - { - for (std::size_t i = 0; i < 10000; ++i) - { - const T v = T(123.456 + i); - - if (details::is_true(details::numeric::nequal(details::numeric::fast_exp::result(v),details::numeric::pow(v,T(1))))) - return false; - - #define else_stmt(N) \ - else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp::result(v),details::numeric::pow(v,T(N))))) \ - return false; \ - - else_stmt( 2) else_stmt( 3) else_stmt( 4) else_stmt( 5) - else_stmt( 6) else_stmt( 7) else_stmt( 8) else_stmt( 9) - else_stmt(10) else_stmt(11) else_stmt(12) else_stmt(13) - else_stmt(14) else_stmt(15) else_stmt(16) else_stmt(17) - else_stmt(18) else_stmt(19) else_stmt(20) else_stmt(21) - else_stmt(22) else_stmt(23) else_stmt(24) else_stmt(25) - else_stmt(26) else_stmt(27) else_stmt(28) else_stmt(29) - else_stmt(30) else_stmt(31) else_stmt(32) else_stmt(33) - else_stmt(34) else_stmt(35) else_stmt(36) else_stmt(37) - else_stmt(38) else_stmt(39) else_stmt(40) else_stmt(41) - else_stmt(42) else_stmt(43) else_stmt(44) else_stmt(45) - else_stmt(46) else_stmt(47) else_stmt(48) else_stmt(49) - else_stmt(50) else_stmt(51) else_stmt(52) else_stmt(53) - else_stmt(54) else_stmt(55) else_stmt(56) else_stmt(57) - else_stmt(58) else_stmt(59) else_stmt(60) else_stmt(61) - } - } - - return true; - } -} +} // namespace exprtk #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) # ifndef NOMINMAX @@ -39023,6 +39254,9 @@ namespace exprtk { namespace rtl { namespace io { namespace file { namespace details { + using ::exprtk::details::char_ptr; + using ::exprtk::details::char_cptr; + enum file_mode { e_error = 0, @@ -39131,11 +39365,11 @@ namespace exprtk switch (mode) { case e_write : reinterpret_cast(stream_ptr)-> - write(reinterpret_cast(view.begin() + offset), amount * sizeof(typename View::value_t)); + write(reinterpret_cast(view.begin() + offset), amount * sizeof(typename View::value_t)); break; case e_rdwrt : reinterpret_cast(stream_ptr)-> - write(reinterpret_cast(view.begin() + offset) , amount * sizeof(typename View::value_t)); + write(reinterpret_cast(view.begin() + offset) , amount * sizeof(typename View::value_t)); break; default : return false; @@ -39150,11 +39384,11 @@ namespace exprtk switch (mode) { case e_read : reinterpret_cast(stream_ptr)-> - read(reinterpret_cast(view.begin() + offset), amount * sizeof(typename View::value_t)); + read(reinterpret_cast(view.begin() + offset), amount * sizeof(typename View::value_t)); break; case e_rdwrt : reinterpret_cast(stream_ptr)-> - read(reinterpret_cast(view.begin() + offset) , amount * sizeof(typename View::value_t)); + read(reinterpret_cast(view.begin() + offset) , amount * sizeof(typename View::value_t)); break; default : return false; @@ -39218,12 +39452,11 @@ namespace exprtk template file_descriptor* make_handle(T v) { + const std::size_t fd_size = sizeof(details::file_descriptor*); details::file_descriptor* fd = reinterpret_cast(0); - const std::size_t fd_size = sizeof(details::file_descriptor*); - - std::memcpy(reinterpret_cast(&fd), - reinterpret_cast(&v), + std::memcpy(reinterpret_cast(&fd), + reinterpret_cast(&v ), fd_size); return fd; } @@ -39264,18 +39497,18 @@ namespace exprtk inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) { - std::string file_name = to_str(string_t(parameters[0])); - std::string access; + const std::string file_name = to_str(string_t(parameters[0])); if (file_name.empty()) return T(0); - if (0 == ps_index) - access = "r"; - else if (0 == string_t(parameters[1]).size()) + if ((1 == ps_index) && (0 == string_t(parameters[1]).size())) + { return T(0); - else - access = to_str(string_t(parameters[1])); + } + + const std::string access = + (0 == ps_index) ? "r" : to_str(string_t(parameters[1])); details::file_descriptor* fd = new details::file_descriptor(file_name,access); @@ -40696,18 +40929,22 @@ namespace exprtk { namespace information { - static const char* library = "Mathematical Expression Toolkit"; - static const char* version = "2.7182818284590452353602874713526" - "624977572470936999595749669676277" - "240766303535475945713821785251664" - "274274663919320030599218174135966"; - static const char* date = "20220101"; + using ::exprtk::details::char_cptr; + + static char_cptr library = "Mathematical Expression Toolkit"; + static char_cptr version = "2.71828182845904523536028747135266" + "2497757247093699959574966967627724" + "0766303535475945713821785251664274" + "2746639193200305992181741359662904"; + static char_cptr date = "20230101"; + static char_cptr min_cpp = "199711L"; static inline std::string data() { static const std::string info_str = std::string(library) + std::string(" v") + std::string(version) + - std::string(" (") + date + std::string(")"); + std::string(" (") + date + std::string(")") + + std::string(" (") + min_cpp + std::string(")"); return info_str; } diff --git a/server/src/main.cpp b/server/src/main.cpp index eb4feaa1..026a7ef3 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -270,8 +270,19 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl typedef exprtk::expression expression_t; typedef exprtk::parser parser_t; const std::string expression_string = Watchdog(ID)->m_aRule; + int ClientID = ClientNetToClient(ClientNetID); + std::string username = Client(ClientID)->m_aUsername; + std::string name = Client(ClientID)->m_aName; + std::string type = Client(ClientID)->m_aType; + std::string host = Client(ClientID)->m_aHost; + std::string location = Client(ClientID)->m_aLocation; symbol_table_t symbol_table; + symbol_table.add_stringvar("username", username); + symbol_table.add_stringvar("name", name); + symbol_table.add_stringvar("type", type); + symbol_table.add_stringvar("host", host); + symbol_table.add_stringvar("location", location); symbol_table.add_variable("load_1",load_1); symbol_table.add_variable("load_5",load_5); symbol_table.add_variable("load_15",load_15); @@ -310,7 +321,6 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl if (expression.value() > 0) { - int ClientID = ClientNetToClient(ClientNetID); time_t currentStamp = (long long)time(/*ago*/0); if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval) { @@ -330,11 +340,11 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl sprintf(encodeBuffer, "【告警名称】 %s \n\n【告警时间】 %s \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s", Watchdog(ID)->m_aName, standardTime, - Client(ClientID)->m_aUsername, - Client(ClientID)->m_aName, - Client(ClientID)->m_aType, - Client(ClientID)->m_aHost, - Client(ClientID)->m_aLocation); + username, + name, + type, + host, + location); char *encodeUrl = curl_easy_escape(curl, encodeBuffer, strlen(encodeBuffer)); //standard url From ed330bd7850fad90a4d78a328aabcfba225855f9 Mon Sep 17 00:00:00 2001 From: windows11 Date: Mon, 16 Oct 2023 17:07:57 +0800 Subject: [PATCH 013/134] c style --- server/src/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index 026a7ef3..d24d6057 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -340,11 +340,11 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl sprintf(encodeBuffer, "【告警名称】 %s \n\n【告警时间】 %s \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s", Watchdog(ID)->m_aName, standardTime, - username, - name, - type, - host, - location); + username.c_str(), + name.c_str(), + type.c_str(), + host.c_str(), + location.c_str()); char *encodeUrl = curl_easy_escape(curl, encodeBuffer, strlen(encodeBuffer)); //standard url From a177345858b096d8665c22e16a85e6e3d19f5414 Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 16 Oct 2023 17:53:46 +0800 Subject: [PATCH 014/134] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=9A=84=E8=AE=A1=E7=AE=97=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加静态字符串的计算支持 username / name / type / host / location --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 46997f76..a980f6c8 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ [![Python Support](https://img.shields.io/badge/python-3.6%2B%20-blue.svg)](https://github.com/cppla/ServerStatus) [![C++ Compiler](http://img.shields.io/badge/C++-GNU-blue.svg?style=flat&logo=cplusplus)](https://github.com/cppla/ServerStatus) [![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](https://github.com/cppla/ServerStatus) -[![Version](https://img.shields.io/badge/Version-Build%201.1.0-red)](https://github.com/cppla/ServerStatus) +[![Version](https://img.shields.io/badge/Version-Build%201.1.1-red)](https://github.com/cppla/ServerStatus) ![Latest Version](http://dl.cpp.la/Archive/serverstatus_1.0.9.png) -`Watchdog🐶已经加入,触发式告警。 interval只是为了防止频繁收到报警信息造成骚扰,并不是探测间隔。` +`Watchdog触发式告警,interval只是为了防止频繁收到报警信息造成的骚扰,并不是探测间隔。 同时为了防止海外机器闪断报警,也加入username、name、type等静态字符串参数的计算支持。` # 目录: @@ -48,7 +48,7 @@ wget --no-check-certificate -qO client-linux.py 'https://raw.githubusercontent.c * light:https://github.com/orilights/ServerStatus-Theme-Light ,预览:https://tz.cloudcpp.com/index3.html - + # 手动安装教程: @@ -67,7 +67,7 @@ cd ServerStatus/server && make #### 二、修改配置文件 ```diff -! watchdog rule 可以为任何已知字段的表达式(不包括name, type, host, location, uptime,字符串无法参与计算) +! watchdog rule 可以为任何已知字段的表达式 ! watchdog interval 最小通知间隔 ! watchdog callback 可自定义为Post方法的URL,告警内容将拼接其后并发起回调 @@ -94,8 +94,8 @@ cd ServerStatus/server && make "watchdog": [ { - "name": "服务器负载高监控,排除内存大于32G物理机", - "rule": "cpu>90&load_1>4&memory_total<33554432", + "name": "服务器负载高监控,排除内存大于32G物理机,同时排除俄勒冈机器", + "rule": "cpu>90&load_1>4&memory_total<33554432&name!='俄勒冈'", "interval": 600, "callback": "https://yourSMSurl" }, @@ -106,8 +106,8 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "服务器宕机告警", - "rule": "online4=0&online6=0", + "name": "服务器宕机告警,排出俄勒冈,排除s02", + "rule": "online4=0&online6=0&name!='俄勒冈'&username!='s02'", "interval": 600, "callback": "https://yourSMSurl" }, From d70a56a767e7da6074fc776e8a7d1edcd99332b6 Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 16 Oct 2023 18:35:03 +0800 Subject: [PATCH 015/134] =?UTF-8?q?=E6=9B=B4=E5=8A=A0=E4=B8=B0=E5=AF=8C?= =?UTF-8?q?=E7=9A=84=E9=99=90=E5=88=B6=E6=9D=A1=E4=BB=B6=E5=92=8C=E8=A7=84?= =?UTF-8?q?=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更加丰富的限制条件和规则 --- server/config.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/server/config.json b/server/config.json index cf50a8c0..c60018ff 100644 --- a/server/config.json +++ b/server/config.json @@ -40,26 +40,26 @@ ], "watchdog": [ { - "name": "cpu high warning", - "rule": "cpu>90&load_1>3", + "name": "cpu high warning,exclude username s01", + "rule": "cpu>90&load_1>5&username!='s01'", "interval": 600, "callback": "https://yourSMSurl" }, { - "name": "memory high warning", - "rule": "(memory_used/memory_total)*100>90", + "name": "memory high warning, exclude less than 1GB vps", + "rule": "(memory_used/memory_total)*100>90&memory_total>1048576", "interval": 300, "callback": "https://yourSMSurl" }, { - "name": "offline warning", - "rule": "online4=0&online6=0", + "name": "offline warning,exclude name node1", + "rule": "online4=0&online6=0&name!='node1'", "interval": 600, "callback": "https://yourSMSurl" }, { - "name": "ddcc attack", - "rule": "tcp_count>500", + "name": "ddcc attack,limit type Oracle", + "rule": "tcp_count>600&type='Oracle'", "interval": 300, "callback": "https://yourSMSurl" }, From 88229b2f4a3eb4ecf92c829d350ba349fd7466cb Mon Sep 17 00:00:00 2001 From: windows11 Date: Mon, 16 Oct 2023 19:35:22 +0800 Subject: [PATCH 016/134] =?UTF-8?q?=E5=86=85=E7=BD=AE=E4=B8=80=E4=B8=AAlig?= =?UTF-8?q?ht=20theme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/assets/favicon-65bd9f8a.png | Bin 0 -> 18188 bytes web/assets/index-282247e3.css | 1 + web/assets/index-982ea826.js | 1 + web/image/flags/ac.svg | 76 + web/image/flags/ad.svg | 150 + web/image/flags/ae.svg | 6 + web/image/flags/af.svg | 81 + web/image/flags/ag.svg | 14 + web/image/flags/ai.svg | 758 ++++ web/image/flags/al.svg | 5 + web/image/flags/am.svg | 5 + web/image/flags/ao.svg | 13 + web/image/flags/aq.svg | 5 + web/image/flags/ar.svg | 32 + web/image/flags/as.svg | 72 + web/image/flags/at.svg | 6 + web/image/flags/au.svg | 8 + web/image/flags/aw.svg | 186 + web/image/flags/ax.svg | 18 + web/image/flags/az.svg | 8 + web/image/flags/ba.svg | 12 + web/image/flags/bb.svg | 6 + web/image/flags/bd.svg | 4 + web/image/flags/be.svg | 7 + web/image/flags/bf.svg | 7 + web/image/flags/bg.svg | 7 + web/image/flags/bh.svg | 4 + web/image/flags/bi.svg | 15 + web/image/flags/bj.svg | 14 + web/image/flags/bl.svg | 7 + web/image/flags/bm.svg | 97 + web/image/flags/bn.svg | 36 + web/image/flags/bo.svg | 676 ++++ web/image/flags/bq.svg | 5 + web/image/flags/br.svg | 45 + web/image/flags/bs.svg | 13 + web/image/flags/bt.svg | 89 + web/image/flags/bv.svg | 13 + web/image/flags/bw.svg | 7 + web/image/flags/by.svg | 20 + web/image/flags/bz.svg | 145 + web/image/flags/ca.svg | 4 + web/image/flags/cc.svg | 19 + web/image/flags/cd.svg | 5 + web/image/flags/cefta.svg | 13 + web/image/flags/cf.svg | 15 + web/image/flags/cg.svg | 12 + web/image/flags/ch.svg | 9 + web/image/flags/ci.svg | 7 + web/image/flags/ck.svg | 9 + web/image/flags/cl.svg | 13 + web/image/flags/cm.svg | 15 + web/image/flags/cn.svg | 11 + web/image/flags/co.svg | 7 + web/image/flags/cp.svg | 7 + web/image/flags/cr.svg | 7 + web/image/flags/cu.svg | 13 + web/image/flags/cv.svg | 13 + web/image/flags/cw.svg | 14 + web/image/flags/cx.svg | 15 + web/image/flags/cy.svg | 6 + web/image/flags/cz.svg | 5 + web/image/flags/de.svg | 5 + web/image/flags/dg.svg | 129 + web/image/flags/dj.svg | 13 + web/image/flags/dk.svg | 5 + web/image/flags/dm.svg | 152 + web/image/flags/do.svg | 6745 +++++++++++++++++++++++++++++++ web/image/flags/dz.svg | 5 + web/image/flags/ea.svg | 544 +++ web/image/flags/ec.svg | 138 + web/image/flags/ee.svg | 7 + web/image/flags/eg.svg | 38 + web/image/flags/eh.svg | 16 + web/image/flags/er.svg | 8 + web/image/flags/es-ct.svg | 4 + web/image/flags/es-ga.svg | 187 + web/image/flags/es.svg | 544 +++ web/image/flags/et.svg | 14 + web/image/flags/eu.svg | 28 + web/image/flags/fi.svg | 5 + web/image/flags/fj.svg | 120 + web/image/flags/fk.svg | 90 + web/image/flags/fm.svg | 11 + web/image/flags/fo.svg | 12 + web/image/flags/fr.svg | 7 + web/image/flags/ga.svg | 7 + web/image/flags/gb-eng.svg | 5 + web/image/flags/gb-nir.svg | 132 + web/image/flags/gb-sct.svg | 4 + web/image/flags/gb-wls.svg | 9 + web/image/flags/gb.svg | 7 + web/image/flags/gd.svg | 27 + web/image/flags/ge.svg | 6 + web/image/flags/gf.svg | 7 + web/image/flags/gg.svg | 9 + web/image/flags/gh.svg | 6 + web/image/flags/gi.svg | 32 + web/image/flags/gl.svg | 4 + web/image/flags/gm.svg | 14 + web/image/flags/gn.svg | 7 + web/image/flags/gp.svg | 7 + web/image/flags/gq.svg | 23 + web/image/flags/gr.svg | 16 + web/image/flags/gs.svg | 133 + web/image/flags/gt.svg | 220 + web/image/flags/gu.svg | 23 + web/image/flags/gw.svg | 13 + web/image/flags/gy.svg | 9 + web/image/flags/hk.svg | 30 + web/image/flags/hm.svg | 8 + web/image/flags/hn.svg | 18 + web/image/flags/hr.svg | 58 + web/image/flags/ht.svg | 116 + web/image/flags/hu.svg | 7 + web/image/flags/ic.svg | 7 + web/image/flags/id.svg | 4 + web/image/flags/ie.svg | 7 + web/image/flags/il.svg | 14 + web/image/flags/im.svg | 36 + web/image/flags/in.svg | 25 + web/image/flags/io.svg | 129 + web/image/flags/iq.svg | 10 + web/image/flags/ir.svg | 219 + web/image/flags/is.svg | 12 + web/image/flags/it.svg | 7 + web/image/flags/je.svg | 45 + web/image/flags/jm.svg | 8 + web/image/flags/jo.svg | 16 + web/image/flags/jp.svg | 11 + web/image/flags/ke.svg | 23 + web/image/flags/kg.svg | 15 + web/image/flags/kh.svg | 61 + web/image/flags/ki.svg | 36 + web/image/flags/km.svg | 16 + web/image/flags/kn.svg | 14 + web/image/flags/kp.svg | 15 + web/image/flags/kr.svg | 24 + web/image/flags/kw.svg | 13 + web/image/flags/ky.svg | 109 + web/image/flags/kz.svg | 23 + web/image/flags/la.svg | 12 + web/image/flags/lb.svg | 15 + web/image/flags/lc.svg | 8 + web/image/flags/li.svg | 43 + web/image/flags/lk.svg | 22 + web/image/flags/lr.svg | 14 + web/image/flags/ls.svg | 8 + web/image/flags/lt.svg | 7 + web/image/flags/lu.svg | 5 + web/image/flags/lv.svg | 6 + web/image/flags/ly.svg | 13 + web/image/flags/ma.svg | 4 + web/image/flags/mc.svg | 6 + web/image/flags/md.svg | 70 + web/image/flags/me.svg | 116 + web/image/flags/mf.svg | 7 + web/image/flags/mg.svg | 7 + web/image/flags/mh.svg | 7 + web/image/flags/mk.svg | 5 + web/image/flags/ml.svg | 7 + web/image/flags/mm.svg | 12 + web/image/flags/mn.svg | 14 + web/image/flags/mo.svg | 9 + web/image/flags/mp.svg | 86 + web/image/flags/mq.svg | 7 + web/image/flags/mr.svg | 6 + web/image/flags/ms.svg | 33 + web/image/flags/mt.svg | 49 + web/image/flags/mu.svg | 8 + web/image/flags/mv.svg | 6 + web/image/flags/mw.svg | 10 + web/image/flags/mx.svg | 382 ++ web/image/flags/my.svg | 7 + web/image/flags/mz.svg | 21 + web/image/flags/na.svg | 16 + web/image/flags/nc.svg | 13 + web/image/flags/ne.svg | 6 + web/image/flags/nf.svg | 9 + web/image/flags/ng.svg | 6 + web/image/flags/ni.svg | 129 + web/image/flags/nl.svg | 5 + web/image/flags/no.svg | 7 + web/image/flags/np.svg | 14 + web/image/flags/nr.svg | 12 + web/image/flags/nu.svg | 10 + web/image/flags/nz.svg | 36 + web/image/flags/om.svg | 115 + web/image/flags/pa.svg | 14 + web/image/flags/pe.svg | 244 ++ web/image/flags/pf.svg | 19 + web/image/flags/pg.svg | 9 + web/image/flags/ph.svg | 6 + web/image/flags/pk.svg | 15 + web/image/flags/pl.svg | 6 + web/image/flags/pm.svg | 7 + web/image/flags/pn.svg | 53 + web/image/flags/pr.svg | 13 + web/image/flags/ps.svg | 15 + web/image/flags/pt.svg | 57 + web/image/flags/pw.svg | 11 + web/image/flags/py.svg | 157 + web/image/flags/qa.svg | 4 + web/image/flags/re.svg | 7 + web/image/flags/ro.svg | 7 + web/image/flags/rs.svg | 292 ++ web/image/flags/ru.svg | 7 + web/image/flags/rw.svg | 13 + web/image/flags/sa.svg | 26 + web/image/flags/sb.svg | 13 + web/image/flags/sc.svg | 7 + web/image/flags/sd.svg | 13 + web/image/flags/se.svg | 4 + web/image/flags/sg.svg | 13 + web/image/flags/sh.svg | 76 + web/image/flags/si.svg | 18 + web/image/flags/sj.svg | 7 + web/image/flags/sk.svg | 9 + web/image/flags/sl.svg | 7 + web/image/flags/sm.svg | 75 + web/image/flags/sn.svg | 8 + web/image/flags/so.svg | 11 + web/image/flags/sr.svg | 6 + web/image/flags/ss.svg | 8 + web/image/flags/st.svg | 16 + web/image/flags/sv.svg | 594 +++ web/image/flags/sx.svg | 56 + web/image/flags/sy.svg | 6 + web/image/flags/sz.svg | 34 + web/image/flags/ta.svg | 76 + web/image/flags/tc.svg | 50 + web/image/flags/td.svg | 7 + web/image/flags/tf.svg | 15 + web/image/flags/tg.svg | 14 + web/image/flags/th.svg | 7 + web/image/flags/tj.svg | 22 + web/image/flags/tk.svg | 5 + web/image/flags/tl.svg | 13 + web/image/flags/tm.svg | 205 + web/image/flags/tn.svg | 13 + web/image/flags/to.svg | 10 + web/image/flags/tr.svg | 8 + web/image/flags/tt.svg | 5 + web/image/flags/tv.svg | 9 + web/image/flags/tw.svg | 34 + web/image/flags/tz.svg | 13 + web/image/flags/ua.svg | 6 + web/image/flags/ug.svg | 30 + web/image/flags/um.svg | 15 + web/image/flags/un.svg | 16 + web/image/flags/us.svg | 10 + web/image/flags/uy.svg | 28 + web/image/flags/uz.svg | 30 + web/image/flags/va.svg | 479 +++ web/image/flags/vc.svg | 8 + web/image/flags/ve.svg | 26 + web/image/flags/vg.svg | 63 + web/image/flags/vi.svg | 28 + web/image/flags/vn.svg | 11 + web/image/flags/vu.svg | 21 + web/image/flags/wf.svg | 7 + web/image/flags/ws.svg | 7 + web/image/flags/xk.svg | 8 + web/image/flags/xx.svg | 4 + web/image/flags/ye.svg | 7 + web/image/flags/yt.svg | 7 + web/image/flags/za.svg | 17 + web/image/flags/zm.svg | 27 + web/image/flags/zw.svg | 21 + web/image/os/android.svg | 1 + web/image/os/arch.svg | 1 + web/image/os/archlinux.svg | 1 + web/image/os/centos.svg | 1 + web/image/os/debian.svg | 1 + web/image/os/linux.svg | 1 + web/image/os/macos.svg | 1 + web/image/os/raspberry.svg | 1 + web/image/os/ubuntu.svg | 1 + web/image/os/window.svg | 1 + web/index.html | 1 + web/index3.html | 29 + 281 files changed, 18371 insertions(+) create mode 100644 web/assets/favicon-65bd9f8a.png create mode 100644 web/assets/index-282247e3.css create mode 100644 web/assets/index-982ea826.js create mode 100644 web/image/flags/ac.svg create mode 100644 web/image/flags/ad.svg create mode 100644 web/image/flags/ae.svg create mode 100644 web/image/flags/af.svg create mode 100644 web/image/flags/ag.svg create mode 100644 web/image/flags/ai.svg create mode 100644 web/image/flags/al.svg create mode 100644 web/image/flags/am.svg create mode 100644 web/image/flags/ao.svg create mode 100644 web/image/flags/aq.svg create mode 100644 web/image/flags/ar.svg create mode 100644 web/image/flags/as.svg create mode 100644 web/image/flags/at.svg create mode 100644 web/image/flags/au.svg create mode 100644 web/image/flags/aw.svg create mode 100644 web/image/flags/ax.svg create mode 100644 web/image/flags/az.svg create mode 100644 web/image/flags/ba.svg create mode 100644 web/image/flags/bb.svg create mode 100644 web/image/flags/bd.svg create mode 100644 web/image/flags/be.svg create mode 100644 web/image/flags/bf.svg create mode 100644 web/image/flags/bg.svg create mode 100644 web/image/flags/bh.svg create mode 100644 web/image/flags/bi.svg create mode 100644 web/image/flags/bj.svg create mode 100644 web/image/flags/bl.svg create mode 100644 web/image/flags/bm.svg create mode 100644 web/image/flags/bn.svg create mode 100644 web/image/flags/bo.svg create mode 100644 web/image/flags/bq.svg create mode 100644 web/image/flags/br.svg create mode 100644 web/image/flags/bs.svg create mode 100644 web/image/flags/bt.svg create mode 100644 web/image/flags/bv.svg create mode 100644 web/image/flags/bw.svg create mode 100644 web/image/flags/by.svg create mode 100644 web/image/flags/bz.svg create mode 100644 web/image/flags/ca.svg create mode 100644 web/image/flags/cc.svg create mode 100644 web/image/flags/cd.svg create mode 100644 web/image/flags/cefta.svg create mode 100644 web/image/flags/cf.svg create mode 100644 web/image/flags/cg.svg create mode 100644 web/image/flags/ch.svg create mode 100644 web/image/flags/ci.svg create mode 100644 web/image/flags/ck.svg create mode 100644 web/image/flags/cl.svg create mode 100644 web/image/flags/cm.svg create mode 100644 web/image/flags/cn.svg create mode 100644 web/image/flags/co.svg create mode 100644 web/image/flags/cp.svg create mode 100644 web/image/flags/cr.svg create mode 100644 web/image/flags/cu.svg create mode 100644 web/image/flags/cv.svg create mode 100644 web/image/flags/cw.svg create mode 100644 web/image/flags/cx.svg create mode 100644 web/image/flags/cy.svg create mode 100644 web/image/flags/cz.svg create mode 100644 web/image/flags/de.svg create mode 100644 web/image/flags/dg.svg create mode 100644 web/image/flags/dj.svg create mode 100644 web/image/flags/dk.svg create mode 100644 web/image/flags/dm.svg create mode 100644 web/image/flags/do.svg create mode 100644 web/image/flags/dz.svg create mode 100644 web/image/flags/ea.svg create mode 100644 web/image/flags/ec.svg create mode 100644 web/image/flags/ee.svg create mode 100644 web/image/flags/eg.svg create mode 100644 web/image/flags/eh.svg create mode 100644 web/image/flags/er.svg create mode 100644 web/image/flags/es-ct.svg create mode 100644 web/image/flags/es-ga.svg create mode 100644 web/image/flags/es.svg create mode 100644 web/image/flags/et.svg create mode 100644 web/image/flags/eu.svg create mode 100644 web/image/flags/fi.svg create mode 100644 web/image/flags/fj.svg create mode 100644 web/image/flags/fk.svg create mode 100644 web/image/flags/fm.svg create mode 100644 web/image/flags/fo.svg create mode 100644 web/image/flags/fr.svg create mode 100644 web/image/flags/ga.svg create mode 100644 web/image/flags/gb-eng.svg create mode 100644 web/image/flags/gb-nir.svg create mode 100644 web/image/flags/gb-sct.svg create mode 100644 web/image/flags/gb-wls.svg create mode 100644 web/image/flags/gb.svg create mode 100644 web/image/flags/gd.svg create mode 100644 web/image/flags/ge.svg create mode 100644 web/image/flags/gf.svg create mode 100644 web/image/flags/gg.svg create mode 100644 web/image/flags/gh.svg create mode 100644 web/image/flags/gi.svg create mode 100644 web/image/flags/gl.svg create mode 100644 web/image/flags/gm.svg create mode 100644 web/image/flags/gn.svg create mode 100644 web/image/flags/gp.svg create mode 100644 web/image/flags/gq.svg create mode 100644 web/image/flags/gr.svg create mode 100644 web/image/flags/gs.svg create mode 100644 web/image/flags/gt.svg create mode 100644 web/image/flags/gu.svg create mode 100644 web/image/flags/gw.svg create mode 100644 web/image/flags/gy.svg create mode 100644 web/image/flags/hk.svg create mode 100644 web/image/flags/hm.svg create mode 100644 web/image/flags/hn.svg create mode 100644 web/image/flags/hr.svg create mode 100644 web/image/flags/ht.svg create mode 100644 web/image/flags/hu.svg create mode 100644 web/image/flags/ic.svg create mode 100644 web/image/flags/id.svg create mode 100644 web/image/flags/ie.svg create mode 100644 web/image/flags/il.svg create mode 100644 web/image/flags/im.svg create mode 100644 web/image/flags/in.svg create mode 100644 web/image/flags/io.svg create mode 100644 web/image/flags/iq.svg create mode 100644 web/image/flags/ir.svg create mode 100644 web/image/flags/is.svg create mode 100644 web/image/flags/it.svg create mode 100644 web/image/flags/je.svg create mode 100644 web/image/flags/jm.svg create mode 100644 web/image/flags/jo.svg create mode 100644 web/image/flags/jp.svg create mode 100644 web/image/flags/ke.svg create mode 100644 web/image/flags/kg.svg create mode 100644 web/image/flags/kh.svg create mode 100644 web/image/flags/ki.svg create mode 100644 web/image/flags/km.svg create mode 100644 web/image/flags/kn.svg create mode 100644 web/image/flags/kp.svg create mode 100644 web/image/flags/kr.svg create mode 100644 web/image/flags/kw.svg create mode 100644 web/image/flags/ky.svg create mode 100644 web/image/flags/kz.svg create mode 100644 web/image/flags/la.svg create mode 100644 web/image/flags/lb.svg create mode 100644 web/image/flags/lc.svg create mode 100644 web/image/flags/li.svg create mode 100644 web/image/flags/lk.svg create mode 100644 web/image/flags/lr.svg create mode 100644 web/image/flags/ls.svg create mode 100644 web/image/flags/lt.svg create mode 100644 web/image/flags/lu.svg create mode 100644 web/image/flags/lv.svg create mode 100644 web/image/flags/ly.svg create mode 100644 web/image/flags/ma.svg create mode 100644 web/image/flags/mc.svg create mode 100644 web/image/flags/md.svg create mode 100644 web/image/flags/me.svg create mode 100644 web/image/flags/mf.svg create mode 100644 web/image/flags/mg.svg create mode 100644 web/image/flags/mh.svg create mode 100644 web/image/flags/mk.svg create mode 100644 web/image/flags/ml.svg create mode 100644 web/image/flags/mm.svg create mode 100644 web/image/flags/mn.svg create mode 100644 web/image/flags/mo.svg create mode 100644 web/image/flags/mp.svg create mode 100644 web/image/flags/mq.svg create mode 100644 web/image/flags/mr.svg create mode 100644 web/image/flags/ms.svg create mode 100644 web/image/flags/mt.svg create mode 100644 web/image/flags/mu.svg create mode 100644 web/image/flags/mv.svg create mode 100644 web/image/flags/mw.svg create mode 100644 web/image/flags/mx.svg create mode 100644 web/image/flags/my.svg create mode 100644 web/image/flags/mz.svg create mode 100644 web/image/flags/na.svg create mode 100644 web/image/flags/nc.svg create mode 100644 web/image/flags/ne.svg create mode 100644 web/image/flags/nf.svg create mode 100644 web/image/flags/ng.svg create mode 100644 web/image/flags/ni.svg create mode 100644 web/image/flags/nl.svg create mode 100644 web/image/flags/no.svg create mode 100644 web/image/flags/np.svg create mode 100644 web/image/flags/nr.svg create mode 100644 web/image/flags/nu.svg create mode 100644 web/image/flags/nz.svg create mode 100644 web/image/flags/om.svg create mode 100644 web/image/flags/pa.svg create mode 100644 web/image/flags/pe.svg create mode 100644 web/image/flags/pf.svg create mode 100644 web/image/flags/pg.svg create mode 100644 web/image/flags/ph.svg create mode 100644 web/image/flags/pk.svg create mode 100644 web/image/flags/pl.svg create mode 100644 web/image/flags/pm.svg create mode 100644 web/image/flags/pn.svg create mode 100644 web/image/flags/pr.svg create mode 100644 web/image/flags/ps.svg create mode 100644 web/image/flags/pt.svg create mode 100644 web/image/flags/pw.svg create mode 100644 web/image/flags/py.svg create mode 100644 web/image/flags/qa.svg create mode 100644 web/image/flags/re.svg create mode 100644 web/image/flags/ro.svg create mode 100644 web/image/flags/rs.svg create mode 100644 web/image/flags/ru.svg create mode 100644 web/image/flags/rw.svg create mode 100644 web/image/flags/sa.svg create mode 100644 web/image/flags/sb.svg create mode 100644 web/image/flags/sc.svg create mode 100644 web/image/flags/sd.svg create mode 100644 web/image/flags/se.svg create mode 100644 web/image/flags/sg.svg create mode 100644 web/image/flags/sh.svg create mode 100644 web/image/flags/si.svg create mode 100644 web/image/flags/sj.svg create mode 100644 web/image/flags/sk.svg create mode 100644 web/image/flags/sl.svg create mode 100644 web/image/flags/sm.svg create mode 100644 web/image/flags/sn.svg create mode 100644 web/image/flags/so.svg create mode 100644 web/image/flags/sr.svg create mode 100644 web/image/flags/ss.svg create mode 100644 web/image/flags/st.svg create mode 100644 web/image/flags/sv.svg create mode 100644 web/image/flags/sx.svg create mode 100644 web/image/flags/sy.svg create mode 100644 web/image/flags/sz.svg create mode 100644 web/image/flags/ta.svg create mode 100644 web/image/flags/tc.svg create mode 100644 web/image/flags/td.svg create mode 100644 web/image/flags/tf.svg create mode 100644 web/image/flags/tg.svg create mode 100644 web/image/flags/th.svg create mode 100644 web/image/flags/tj.svg create mode 100644 web/image/flags/tk.svg create mode 100644 web/image/flags/tl.svg create mode 100644 web/image/flags/tm.svg create mode 100644 web/image/flags/tn.svg create mode 100644 web/image/flags/to.svg create mode 100644 web/image/flags/tr.svg create mode 100644 web/image/flags/tt.svg create mode 100644 web/image/flags/tv.svg create mode 100644 web/image/flags/tw.svg create mode 100644 web/image/flags/tz.svg create mode 100644 web/image/flags/ua.svg create mode 100644 web/image/flags/ug.svg create mode 100644 web/image/flags/um.svg create mode 100644 web/image/flags/un.svg create mode 100644 web/image/flags/us.svg create mode 100644 web/image/flags/uy.svg create mode 100644 web/image/flags/uz.svg create mode 100644 web/image/flags/va.svg create mode 100644 web/image/flags/vc.svg create mode 100644 web/image/flags/ve.svg create mode 100644 web/image/flags/vg.svg create mode 100644 web/image/flags/vi.svg create mode 100644 web/image/flags/vn.svg create mode 100644 web/image/flags/vu.svg create mode 100644 web/image/flags/wf.svg create mode 100644 web/image/flags/ws.svg create mode 100644 web/image/flags/xk.svg create mode 100644 web/image/flags/xx.svg create mode 100644 web/image/flags/ye.svg create mode 100644 web/image/flags/yt.svg create mode 100644 web/image/flags/za.svg create mode 100644 web/image/flags/zm.svg create mode 100644 web/image/flags/zw.svg create mode 100644 web/image/os/android.svg create mode 100644 web/image/os/arch.svg create mode 100644 web/image/os/archlinux.svg create mode 100644 web/image/os/centos.svg create mode 100644 web/image/os/debian.svg create mode 100644 web/image/os/linux.svg create mode 100644 web/image/os/macos.svg create mode 100644 web/image/os/raspberry.svg create mode 100644 web/image/os/ubuntu.svg create mode 100644 web/image/os/window.svg create mode 100644 web/index3.html diff --git a/web/assets/favicon-65bd9f8a.png b/web/assets/favicon-65bd9f8a.png new file mode 100644 index 0000000000000000000000000000000000000000..bee2a55e8be332c9121c6a8e817003e25531bd0f GIT binary patch literal 18188 zcma&O1yq$!*FFq~0~|^YjdX)FqI4WWIz*7}?(Xhxkd{`El`~w^ueEjn_1PLhd@8B8*et^wH zuktVpIPgDp;NXOSpKx%XT+n}% zz{lqz{MYmI%OSl^6QIhvg^Iefy1X2pk(~{zfw7&T39Gw}{c{C40e3#&(Zb1@qg#XnV?tpusm<=<0?**Tg}aIvzpvQr76QczF`I2xPseGr%U zcXQx3K`L`+XL~+2Ha9mnRyR&oJ4Z7%4qjefHul$SuV1qOHCUWHY@H3wh=-U&a5s)q8V0XFFiY9W9KcZJkXV0g=uI&z<~d2mkLH|GO_mM+*~R ziT`Q+A0z(nW&f@I^St@qTezE8tBYIMnArX^%Qx)o0&M^1oB!QX%+A`*QQ6+W$mDrx z{%P{xivD-)f8=QVKjr+lH~(%a!1k;M|4lFcrF8$40$L}8D!}%i8Z3lLrn%P+2M2?b z78g-*hd=m?oTc)6?kR`g$JEP&z|~-<4TUj$Ql*!OIKNma$#3+oWP(r@TkHGAN250q zM)?!!M!2{wfw}%~-tB1c?RT?|Ty`IhjULuMHEpZb%QZdRv*s8a{`DGj8oLoP+icj% zmIy`w!{GjZ|6AsPhbMt`4uVDV;v+u&bZv~y!jpVKr!xJEUWLp`%D!bUsr7KP5y?(W z+oyoPy=vkB9a|$qfGl&chX8WzE!5FbojxJ)2NCmd2dWLiZ=jXItAV;U**$Du3V z>H=%#$evup6%CJaYr$&??xQU3;g0vvG+q)4eQOXDYIK*HImwX+Wn_BQ-kN74L3vH%CP{D&m7mC>9F%jW`@ApVEwiX$1$0Sa41FWq+a0%TeTHWdswSwEb&i?dZ;x z>|F~`POw(986j*hg9Z+MqEIXT zTLlCcH<$#O@pRzukK1vHPe{m5 zMCJO}pV&k#s8LoFxwOEXSv(Ltcmq1yeLhAk9X%b5-V5Fx2|2G1*23P;2~U24#=i(L zT^hW;7AKnZJ5HHW$bMYDhA&XXAY=aJ0tv#T$i)IWiQxgwnN!E-=#h2QxIc{^)!X?M zH`Y2E&XaEZ#3hJVcvm||`o_I8p0vhvwCS#}b*0qF2~n|#;u-=f!SeSn4kbfrp#RQ* z`x-g5{AGuQ*JF?5@bH+GpW+XvI>bVsInoydF+^ORLpNqR$DNUw)vhes;X+B5-u4v& z@R0D+(F8+&kX1do%v^TI+7@wxjZZK}W?e(emk4DR6e%X?G*(V_iUz;Y@aQ}nkI!X( zyAPt0e;}BG0<~M>gD?~-`M#}YH4|&EW8qrdME(b&=4QS$yan>8W!=_ObJA_WU!m2{%LGqHvT3$>zkUCMzrJG?6Z}ETZhKjr z4Kx{lVJ=I%a!oS1~DnI$pu3m4o=w;Ph-o@Be zr7sVab2~fd^TXdHuw+Sk{1E@8 zRE_O~i#x`qt#}Qm4NVHo6K9Y5C5Q9*S_A9#@9qEuM7t4})*u)&usl`cVt-XZR&GZM z>ZgyVsj^I^n{~QxIwO?8g?)Igr9ZgO&TH73A8w;k^85-zP!|hm;ou`uNLESdDK4D^ zZm<0GTFyEj)ndYX%|Vl^1?z>sTsj&zQ*yFgEEPVEyal8b0#XvN#jaIBkxaqc(=FU-9ZFe)5EzVVEo3~pbNCbG z$mtI@!T0Kp>%IjD9M%4{*JB%z!sk;S+*uw&=|&uyrHH7DJydY;C}=pKI;i{8$PseK zQ{R@=+;&M>ij{=#mIzGzDWafG0-e}pVCrh|mSFm|lIxHWwHifGDh9~V9$EIIKvm^h z+|%{d!Oh*3@T*Vqg0m~{V4B_u@$u&em3}T)b4783#db}hZqV&mIB+5V>&8VH{f%Lk zp{JYEs7fLMvX7~%c0b|+>0434!>5h8?l#Bx>@IDD+w98&ixZMx09)(4{f4&Y{xlI! zxkJ0b_N~%jiE*>0bd)5#g+b1|U1yEj&!#Qz8dHO(OME)_BPlr0WCF6#gA~l$_+r_q zQuuqr_hn20u@w!Nc*np1{rZyQnO)H+(dW5NCqdX;3mu?88E7+VY8A}(tydSwvZZmq ze=HM$nFNkNRJTjk^>1{&`s$1-_}nb>u3sWUYN7uAweg*I4j`uXxrwcdE8)L~S9hEN zV9?|T|Q$!X6>9q9`-fv&I!%>BZ<$noi*Tyd*n{(NEUGpo}R7Rb>MPya5a)$4HWO3x$2 ze{PR{a%C?vqH;CARtL-d`i9%q-`)8g(o8ee`wyDlH(m{kHP$8!#yh)06(?eFpzgRz zMTS>iDzwbrhrjP!NqLSdacoyXkaJjWeZ}tRmTkM0kFW3Gv>5x}*F5k7-LD&iT9_6^ zx#Svd(o=I-m>Ju@wXiqFDx5Fw`cGjs?CmTGyI@}u?!+W>92FoM%5_|-GdjeE-3<}o ziwSu424@;TkKKtSA8(&*m)aane7y;~uzK|Yg+_8Rx9h{|TWe5kZ)|L=J)d0cUKN4_ zi*@d~V7lLy`;n;Em%m}nI))gL0N2Rcb@fbQ`0B}Bk*;@X<2gfbftn@+iW2bk>(@~~ zfv4VjpF7b@sa49dc0fhW4?4a(vAL!RAOB^lBw^*{6W*7CKtNbfdoLoSr^9djGv&S8 zWsu?>eg?4k(jywvRld8xc?0*;5o~28Cln7p07fAL!ic#@(rrA*{)x|mnqKfGz?_c? zj(%@YW5TrV=W&u>n~B+D&qV(gZ}vcp4F}al$IRYK?dk6}+kIv}7mp<$F%30>q~LcM z1T-o5997?F_^c)UCMaJxf0&x+eMbTfPk~8GPkfAt^|PwQT+N``jwy`*@-)1L45pIJWUZI7^3&3SMhLm<%1U;BWTdNhE_DZ9c=DJgiw;Tz&*f}WEKwx#9!Ulql zYLkP*NHAie7&a=7zdr-I_ThRjmYTIsX~W*`uG5AB+NB5u31}bl<<`_sp_7B*PwL(r zB)Xoc2=Eh04c&u#QBlGj9(pU3a=7S0c!3O(xq0oj>#M&N+o>J{3bae4q-{Zj{Y=~j zhzD#--`&=cM^b%D^b>}RPU%aVyv#mS25kI;~sQo3?C)I+!(%Ef} zbw_U2jRb zDB<9hz%>F9%-V#nSv;TGOnfiZ;gBKQ5wLL4^M0=<%_tU!i}gC3GgNrqgb3S;=#1)> z;h=Z#==bP)1{ol=)XT2iUmwkGtm5igf|Wl5&|rJifMu?{7((ma?)kezO9-$@=Tgge zEK7eM`?!%qcR7v*IkCXvVRbMPmy5VQyY{(Xf6IFQQjbuKOHkmVPIfGMTJTDk)NxEq zy#$LZF5YrfmUhhZd&~qN5bUt;4ZenC!E(RWTXrrj>bhQ_aNCQV0f#WdO=$qVy5raA zkzdt*Qmonu3iw=Je=0PIP#eD-#N z|H`<;pc){Y5 zLV69JXQGPANwJR6Wr473uxJ;w?d(v?E;2~GJ1!*N5*vU?(!znYXHmN!I_6q;#vu6= z43OuczO@AoLRY23JNq#;y5cL?ODwPa} z7mEb1MCkrz=zvFkdaLDNzA}Q2b=BX05rRwpiloijsEemd5qV6$`I0#mOV3|ib}nvYr<@uFr%C^Nl&u5A5X zgPmk2hcDx+S41}#n+4Qq={g)4qRuaYtIIf;DP(73$)**vJZ@Gx!xuN&;D;{JnoVKV z4_ik>uOnr{xb<|$?`p@5vGE~3Qnsk?Un5FsckaktV#|Tv&LJ||XIRusiR$rNLvj0Q zQ^c%8TCe6-3DRPAs%AyBJy4d9=sa%vjoTP-9a&qC92y4pVuoJ)OmMoFcW%BTlsBs^ z%oR4omBi%O2tS6Z%YLC6lN-UYIS-k_H?RiVQR=@=-^RQW%HTIK*K`1|iB%MEV*i{< zhW+)fS)FI1BqNOvzUb;A6a3*iGZEd-hm9z{6GW@Ha{=F6vM6?Dqx&{i=Gh<6?;j*8+cjnQ?#o@;zYz61>p(k3AD zfZ~1s!^9_3uNC8PNjGOc-G-_T6~AtABU>Ykh;mGMGG;Aa7kJOI_H5K7=5v+mq}?CT z#6|Dlqe#5o^}fFa@DJ+%)6{+nejoJ7j7&AsireR@=sU=fY@5aoK~PCaihx_iLQUY$ zT{w!gZcI)#i)AkHp1{G;aw{>Yl-v8FtkK7byTL)@9mqa1^0-Czc0BJ-GO3qq&cuR` zHoc6InC(#+<5&KYxc5l>GxJ!dVdj?aI0gL*vqNt^$uYh*oJyxJoerM{zf2_~rTZd3 zn-~gM0HWAL%^TC1SVZ;uLa#!cOro7Qyf7*6nY)#9@Xq3@M8-_6w^@hnY*p2-kyO7& zt%dc}f@o3Ln@wv6jNBvFeRpxAxk+)?(fzRX>RZO+e|BrMx_5o7@I2?nEhDE*<;bVkszy&Ymg)|2)!u*%%@kN!gvlLR@Pvp=z#e|Byv! zJ6M3ZXY6-5$T6%R1hRLgSw3mBn8|oh=F{z?uLIQk*CnjzoO{ErEpLkUP?)X;#sBK{ z3E{N$y@FXOw|HF53)l0gEcFAm@~72BoXXY64B(EkoIFbA^71zMQ|+`R2w#zX|1+DBU?Gjj4+i| z)8$jIJw) zNbc8b^OyHmlY@qY+|H=P8D4I`v1H=SC7Q^jBb=!0`2R@tctaELpUR(Hf3UD@xvS*> z8{|Vy@-u+v)^eu(!M%UPym6LoYr)!AviZf9o0QIHQ8|8JwbidezRqP))|e!JgzZci zg7MxIR+uaO3Gx?5QP?#P!94Jc%(z~mgfLm+S-HDK zQKBbbu?LRGC1v5+YuewED3laLCsXZ-iP8aZkHf8}>a+v}#!j2AEn6=0ISZrA%th65Nekk=QU?&eJIE}QuNjrOtKaDIv zkdYB({g&3Pa1QL@L`@R&=Hp~&ZAk`Eg^z=ePE%eAeL|U|^J|*e(OY@mrMT*h%uEYC zkD+4)^J67MkoJ@Lx6YOk8ccE_f%*~REbXk(6k~!^lL0I;_*8zWGvb@YP51d&n{8y2 z%H}~LR1g)@;&C(qE}jmquGCrxHg`~SXq}L~xP(5d7OGIh8V5lO=K2!JOOD`_AYgZ1 zlwkc~=F#r8L2hnL$|bux3m@;BL^ivN_^bNksGw}Jda_-8TKv`$@7p_wRADd83q4#^ z-l*Z>Mr|K8Z3DHxq4<){U?j3Lrxr)Mf|h_Z?-wz#B!<%O;6PM(LktJM$jb&#?ryY8 zRkH9o)jbXhZa}i+o9e-V4wx*f{O8)TzlSx+E=l4;nmEIs+G?5g$C{ zNT%=3_|}e+Ch;os^Sj{@^WqCiy&Auw!!yf#Mc-mo#v*v{eQa0h)C4*@?{8*JUp8C^ zOOP6kEEI{8DIRgijKobQkZxqx&5xYxCKsQwLFh8LxWs;A@O_kT<*Y+=V_vUeS$rAX zC5(CQv6B!f*37UmA$Cj1boY~lpxo`a?o;%fbso(B=cCxk$eMHWb`Zg1{;nMlnZeGg z*{FKDz=F@HI^rbEVytq@Y@i?iuSo1wq=iB5B|li)2Gc&JJ)-=pX9hBes&4*{3p~`T zarapeMAsFZ!~SjW1I;B&7+VuU%o)&X%0|1&Hju`ftxo~X|3-3{XZt!`5f*?p3?LAO z0istNpn}XB5{|;)vm%e{d464}$^qzocX@^a0w~|&ijd8zAmeX8Q?i6i^43a&mnA6YQ*0=Y zShSM*>2%RznHbEII`}RT%RU#8>gC8GI!cxeYY5|S9r^d0d|>gHV^Sf{i}oIa$0`82 z8Nl%VTeBhvG$}~@7akr82M^s20338=o<>?0c(!>FjIdF#zq)BB`%*SsiIx`;PwFS& z7^$`n#DvMIe^&J!mdXnO>W6?AP3V{VHifG>U#t+b@Eg&LOThguk3k$WrW+5JRDX>_ zce?h!%HJDQ4P}8wxz&#$Xmv1Nz-!r1cgmSmiu&Y*>1B^EF+4*c z$uNNpUL7ew0l1Yu`!5%GgF)6$yMkOr-YE9Aa|aZ3<5^;`6Fh*UQNrcMp0{v=50nF= zem3_R48}KY0dW5g5<2S$;7C(ps!i-_(n~ZANfM;AQ00CT)|gaQZW%5xsQjp^MqF>b zfLAtdS;UtVk{I}S7`W{D2CTkx!|f`BNJGuSNo3d@x8_{(#6zek_pwX@?NEJi!_{(z zjH##z<1J$%rtnTd*m;$Zr*vY-;g4{%4t*rlru_?o6aKG>!Y2?}+G7Fwmi~l6rxTM` zck~g2R4i!fga--04oC_#zCsQV%?yfUcIB0Gvf%8^*0xzbKfz0VG4nnTun&$%iW(XR zqDT_4^<-K`^A8H&zA@bufkR*N)@%O70n+QY;R-x zs&8m|4u{353TUc23YG6Ku=t7krYIAQraz+fwk@J2`NXQ2019v-X#62K6FAoll%E(! zx52S#6q%rV=hwGFRGXoYM8FVBMdI{R(T_% z02;z4vsheytl9POq96Mq)B+&e)Cl}OBQkmSTBwWypjo^--LA7>U6b;7B z+u!7bQki$~UVs=BfRoJQNHdEUz&MS0dX;Rw>ge#j!r$5H;7ksg^!u{aJO-JzY8sqn zes^br_7%AP&)W8sd%LRfVRnCnTVx{3`3o|g&k!Uv6+k7GFa)s=BRlhZo&N;M7b(Ej zoYJ-voTHoh;L%x&WdKQxzBG&J{*4C*Nw0i%zJEIS8M(#-?@-lySF>82e(dt@(>Ol- zFDaWFgeC)UFG{Fl;bqS~v|m*JOpt7kSkh$ss?$v@2vA}oXVhwO6{Grb91C7;wnm27 zMo&8a*h|f~bq)+A^pIL$tA>elD)J^f0mkGYj~^wIF1+H#`mXDP`vOH&6G z|9!eF;{6$@FxjzqM=w8YZ9p^-J>Sr0xA)O0wKi%uYy|snPrKY3w@w@9NlrO75q_qP zt-rOg6*#Cdti<)TZ1j~yg`cQAY8-Cjk$sr>MWUG)Z#z2_Y9ejgT&D-pG9b{Ctzc}3 zMT{0`cKZ%#-Ooclnbt8nw`0VffX&4$E*7P5|HM5^X2K-V$%#nQ^HZ8!A)lsA);OgwJUo z?rQhQsiK`DFtWh*xxr{UfB|G6JhISsOecQ5ud1&pna=Ecu`Mo@Bu?C4u2{2cj1Kf& z!bN=Fl)PO-5WvoIz%ChWQSJexIrkUrI|-o}#k}-GK03PJ$t2^dPvQFb+pzqQ$AncF zJuhR00ieR@YcjaKBf-WN+NkA@v=e~GlCdHr(ez07u?uViI*|K5J~H&8NK#6-> z8)zVaBUxNM`8n3EnUY*;<18Gf2<@n2OgEIZW~$};=rM0nQCrTPx5gE2@F=O zz`+*){0`wl4}%_4fMfmMirW53%Ju6o(PUEduht!LZL=+v5!Gp(JhLv6?DpE)By#%V z4*E=^%HbDoVRE1dC#Bsvqi@en?7Z9n0pDL!Zi83`h5pdvOdb@%$8}KM4_M{ID zjhB>^LFKwcKFy`AQ9&cKFE$B0RcTK3i?GtGcwl^;;ER=0q1giFr#8jG5|^ zzQrFXRg??e)jO`DgN*@1lz_!5XBFl@gqz>~%9bd_CAxoodVKcr_j+~6N$F3pm~}9F z8zpBFc9mq0iAi~i3i;>cVR17^3;X9{A^op{zhB&Lz9%W4O_$OY4&AmKxEqYn1`dj2 zLWqt$bWqx=a4IZy;vDNs^15XTy<*u!A_ds|wXCf7fXY`K{E5N?~C0ysAv}$( zG@B5j27}Q94fq^ztLGA6nysm}X-#o-n;%_T^O6+l=xDZH6n}X&^L9LFq}symn=(DG zB$r5T4BVe_8)o~jIG}v<`;%e$X1ut|G-a@`ppPz=j#G(H$afzN`!PU8A$~$LHW5EW z!&&*i#2@nbA@9-5%sr9|z9%5J(&4O*%{ zAd~tUp0~YKYNpHC$0fcr;?d`a?`{&!lsBHvl*ncsK;lJJ*ZSDZc&@!GD5)3 zf|7SOk%b2alLb1`JViPcRa0PDHmvt8)<_=)n@S;^7^ny12|rh zmHj0qDTNO9rD69Gf2A%ZuJ4$lMJ0RtrpDDvLn??}io0CI@8yhnY+oO~8G32aZ!erT8Dbta7sp9gBbojZ<@}#ne>;Ur zs+Y9*cc5npk;G{iUfyo3m44wu@uC=K0yMEQ914>G(J6;35F^1SBz`luV%IXCpm7Zc z;+lxhn;9Ha7=Ajr_iADX0W|_8oLEtwJaixs+bE<-7g#+{_~7|TY{JjVOywf#RD9_Nb!-X8V)j{TKxmx1y|N5w)wQmtX0PxKiq-*y zCKF-yvYr$(YgiFbF=3;^W9k6lD#kX;U5k%^BL)k%3u{uoo(P#^1%x*H2g;s82Nn9` zG6jt1%VIaZKNt|BWW5pr&MMfX&>;)9q|$CC$E1XTRP^>$0{SFez#5>}#gIrW7@D~6 zuQ?O|z6zTZjsvv*q$ud98mF^gshavL4gYQ0dQmj4CLlvoYFWn>c6qR zZi;?q1M~viNOYX=$P)TPa%qFiUZ_%V;6Fh9KkCbJrl1#0niQ|8>2UH8|EHtCW9=@) z#%b7%!`y_@a`+nXp?@zH?6ujmFa5Kth~NIV~3|hYe_@ zG<&xc511%(9E1|4%xvK89*T!1)Eg5IXr!nkaKI{#vg!yqo& zUiriGI32px6~Q18oP$@=yRRUJeXv|EeY#3=y&Xa*m1Qva{X7*obh!#^)`NzY3n6@g zB|z}ExsNj%GPg0HVhM;$(XNvEW)6;S4fcW(AiV?m@Ci_U5X>0-=4}m=;M=#=fA<8O zOayDbxQpmsKzQUC<5ceg%BO*C3b-NqMiAPdazr2mQCRH9{a}WN4 z?Vg>aQ^Oy%wL0?QvTuI8f#!cYN!^j|j3tq&J#SLEeD;A1g1hmjt}kaFS>J%gO^}Z> z?ss*3+*z8}Hy$gJf3{-|iFE7t0t$ddEe3uC@&2@wy4$AS@Jcm>@)E<>_HEAR!K!Mp z`&r>%XCj=9|6%hnB>SC7K zL}Ix>z9~57D^(>b{N)cHV~eFhYAPg%6ksE%DCN>3vtTt#a&~1eNj${Ij9S|`V`4o{ zE;d?;igmqz!G7!bqgyjd75xa=fy1H;*!2%tyryFr9fu%+P61kAZ~#Arn&No3gz}fa zL0cO(4*wW|Z-As)Tc9Z1J3z&7yQ0NCso(caJKo+!Cg83*x_n>Uu3aD?*EwKus@3Uy z2`PRy)l}Xz3kjXm-72@vOgU&ESDJ~7BAp8bPmH*V=Fp(hl4tfYkTe2Nnu$<>KTfz_ zq0XCAQgpWm06#mIjwVzp3v|NjSGXAQkE28$m)B#x1SJ6gIe~2J#)E(*{=nfX96SaV zEaq1{XZ$B}NH`99&b2#9CV8OQgPh{d;ZMgMb5c6=)w{gsWjnY5^BRIJiEIYm1#ck| z^kJ#_U6+s_Fowjh%I3)f6>M%1n+(A+mfGjzUO3-My2eN`t2RysXXegzC{rxA#%}l+ z*?}O|*eXY9ez?H*YZ^Z7zMq)iX17j=FJ~S5JiY)(Ea5ieKmCK#wd^_=^*4QZ9fS#Dld46Y?8(B%?bBvK< z!L}!re;z5&)0PKDFxWE=WiUIDrrBbQRmSlxabWnY#-ph(-^1O!idZso$Z{AEin+i3 z!%q8P=YYC!HAeGCJNF3@u`~$3`C#f1irMo^p&d04AENijC1+8p(J`1KOe%|WRAnb_?5>;R9&(tBT>$V3C%i`DXElX8TD4nQ8T> zLCo%zLgC8&Aca#Y(&*z1;NF}lvx={hLUH%O*Bri7*Q?{qG>u`+dr3XQz+F!Hfip4G z4qxuvCp{`#=ackXTki#$5HzC_99WF%0^*?mFL0|6r%(Iat7|6u@&pBPT?w;jhL2?* zsp`4@6U)bb3i)!$wr>#zKnVVJn1V6I`%%;H9c{kjCu*jNsr~D}#?$^15oK!0v$p7E z;3DSV=B8h&@Nbv;MATX;k|4gr>w*U%0Vs*1F-WPE3$)>~kKE3h**^S}t_GUFuflCY z?=>sy?WT;+@1~Bhzah-Z`eK^W&R}Ks90&C^Cp`8bIc{-iIli{0U0#qJyDOQ?qlW>td5{bezd+8z%1nov&_`kz6$!Sm3d)(C zR1t1fcNV!H*knV>6k9(-S;q)X`>s#E$W_g=_Ag(|Nn5oGmrBynfA#kIRh}Lv?dJ8M zHO@SqAo(iU0sP5tqG%uX8q8I`Fciw_DpL0YdbD*Y7yP+88|8WZPJJ*1q&0R)l& zI1G*qNu}%;;H+=HGNgZcb#<$oJqe;;B=p=q3p1OsRW zTZk$67ezoJynM2gCiNW7`Gl2^wv=|+mvbDh+C7NUoMx@W8};(|FYLfPy1^m(f2j1M zFy9~6BFPZt{uC6M4L8VV&d(Z=SGjPB7ufi-8uiy7#`8Rq_o9UISkQOWcBX>q2YY6r=(izW`1q3qOZ&^$gKZ_)DHMTCZD5Jr3(K-b#;M@+vBF&6AVtg z{;E1V*h6mYwfFp(yXWgTcTSW5a?YW+60NZ)-lf zWEygID_J|hO9%|F4z3WfGJ?f>##Sh;R!!gYDigailoXoOqSICLOkgMAGDg1xxFl?j z*W&Ss{y@A*o<37VTH{dNCW7<#-Dvc0)YTxE^|Q@C5!)w(gfs0&&X2E#$HF+Z>Ij&w zBnDno6+XkOQ0g*q5elPd$r`UTNhOlLg7En@Q-vNQ=DsfKu4jH#6_-aT(LdtC$2j_u zA-#}t>Xg2^9hyoR6)L*(FCBSph|ekE(WJ|u#F!J=DFI2#cSm*Nx`O&}^O zPT@j$D?}qYL>DS$DxDfSZOgXi*ybg|K2clsvP7uoSF%5IqY-5)o=ED_AHvrMGFJvw zy@b~;v43zON~`(-v82mqduM>d<0jGFXI7;AV3ulr=cx3%_T%6$gS0mcb&}YUCAVS4 zzxo0MKLa|s-K!)q^tDmjYgZpg_k28WQQt!#qI#=3yZ0PUAb>Tpu)v#Toi&{Qsm&0IVxOda)uNMKA%jE!_?@Lt$jqWEED;4B{?KNb{v@&edCQv2ng zEO6Ee81-1;4C@C1fX!JON5r*zg_- z3s3669?^}U0w5nYJTo{Z#=iqa?{XG$NtVgtKKh#y22;7<28(~Z_oiLcw%aW2WK33F zwyE>Jm(Levv696GP4+W^N?Nul^i?>o01(Im+jv$EtiId zE!eSWm@(Thr#zbKf8Gzi+5k{T0zl3+P(ux6`?!(~+fH1iXawuRz^L{OW&~sg(wY%e zZ;;?4poD<~61jQ3_?hs%hbge{p&iqbkUdN{E%M|>czC72*OTV7+)P2--=rw-Hw;S#5eEUYqMtH9r&+=JQN6YB=gDZ1(%dnhKLqr)X^TA?*oOKSf zwZGPHkw;AmX%uN=e11P3fh>ih-7ozJ;&?ipkDk@KS1pnm55DbW+FRMvu$M*x{{)AA zc-^lct8x?u{WujqHwqSY`4WEPeOv(_tZ>_(cn(Em1{;{1S_zC}1#R?dBMZ)|K&~Jz9 zYerVqfEMBQT2&=V3P!I&JJo5+Pc^wRrysqJX9|p$nQp9n!uM~D&*vCkiV;QvCxnL4 zdh*@ykkmZm=eG~)C4V<)ItYHVsm7(h>^{ZtMwL?NfM+t?2)nMr>g49(^5qy%7#W@= zufZZEg4`mO3`*)rl~vS`P@lFK)#d-ZrVd5dEBcv5Og{sKe)37rPW@bBBLr5^0~Fid@Fk_IgGLLiIRIo6h()(zyG|A2U6B)FE zJALcz^VR0w)FuBJ?4oXbD3F!)1=8d?iG#voW-9`$i&H|H#ayxVc)F>Vjqm)`tXHk4 zJ?P)8Ny;zVKB~}zGp->3^Gtk8uf(E-T&9Gep~QmrZf})gJa~6D6M-3BX=CPIs2Tfa z_TUBTS5t!Xe$=ZCdVjmJ`)DtDk$vQsDXCX-mGBrOxlLViAxt<7y;pWdab)-eKB#2S zL9H?F!suwBJ5vl?9$)_%qqj=ubYO9%zYFwSmV>$P7M3>F6c!AKKiRpRD9tj+SX?bn zdu%GbK+tdAY&Y;(vtMn;J(l8;f}WB(XZ!qG;dSNvY`Umzu-B3hsHxp;yA$42%C% zCt#@-QhY(S^s`?^pPf;z3*!I+o{F4#G#o^ zy|;K~87*^$8yN4PaVeDnJuCUG7ClYboWHw8nU3y#IO{~)Gri?V1UK7lZ5=!`a1$2D zX`JfdKgC2yl4^Y|YzL5D`y}Q|f%}4q!12G2L}R}JEmBH-LizSHjos%5kb={(?38J- zG%%zcJ%%l*_0bofN|AR<;VA!_^Jm(FIYFv}^g95o;H|iQa<;8l-kC4@X{NKVc9YQ| zo!cfS9&2m3XZrFO)5#$*w?-p(@+xqB&CzBv+p1w?C*OMhJBwggx6T&;+a}YINq81T z6F=z_b~U0=jeQVq9(s2tWb{B)mbAbSHmjk491$su`T=e&s@ZvOaK$JmM?mA)#RG@n zBei~(U7jW6i=z7?uQIm=v*{?&9+J%i7Sn;Ra0pAM`5s-cFKZMU^>n%6o|X-levJ$j zHzazZ$xO$8ZVUS)c@iBgE|Y;hXJ}=F*dIrD5-+}qZqYw87<$7h%lA0B=1aB8P`Xwg z>lXC4(&o1o;*Zf$RzV+YQxUrrdp!?e@*C-4pH_#A6n#0${Iig;wJ7-sib#%#QN9a- z%gI+Q-@d3nbi4_pED-?GnCZyX7s6FLNoTQNiwbSggpoQZ z`{cj%wkME2DSTPII9We4uhfj{Hn77j-aLbn8dOqDCt{R#|0(0j@Hsh;>qd=+MdFMv za?3k_|HvOlC($nzF8sA%GZR_D^eQ{@&O{js<&hsHtn@-`@Rt`h`M(TwtNEzO zQ@?vCuFu;>m17WlWlcA7i@)VRS*QIIY4|#Qr>o^L*=KnBdeYp6BD)p*ef?Xjw^22# z>(`Fz^^y6MO0A&Bcm`?D5*FumtrI-S%U(Fz^Rp^7PTK0!Io2O>EfFjnwq|~jh*o01 z21D0WN%dW;I8~F$tfIKA2g5g@aa?4Y0%B+YHn&JE%Fn0TYWvx?d3i_uB-{A;WtJ;d zr|;QN!YaMj2Y-@%mwQ287@cgm+%yy?l_GuaZu-I3u=HCJp)QGnrQsinF$oA)=%AXc zHTXB?-bWyIsNipO&rtpNaBzi@$-&{K7yT8gBLT#62O(;xQ%y}x*=9@E_A8;~TKF;s zm|VUT6kO2W>4@vyo#GM(3pcF{d|Cb=o`Xtdw)1&u)5RHa8yO}3o*C4BP&SwrH^<4CnvGOXPy&QQe!*~a6lRg`rymP zjk0e+kHj^Ugz=vN80gwNNyBb-dTds%$}|m1M4~So)CPDh^l@>H! z0aknKusxn9KSd|kDpGnQ)((TAf)J3=H3Y337s*~(cZJ>qI(N#M!W^PEDtu*A)HBro z2(bBUSnTO?&KG?%Z2D_|*)>Jz4?~{8upw8U2j$jh4xjAU>gW9ESukC!@J7g#;;^~! zKFfY1r1%AJLGk@9P`H?M`s$sYo)Y@DI-f2)T$4t>fj{u9vU%kN%O-}$E|Aet=*5-M zO6|(3>#&%0_BNf@7!{mPV?VZkwiWjidzP<{=luEedh~V=X){xF=)$ipx5p)&(_D;S zf)yy@vl8nI41Z?P(*Ny5`~iSW^Tl^MX7-0{1OmnlbKkvOXWZ>S(u2WW;xjrfXC7z- zs0o$M-;!Pv@n!;<*`99I6xU;!yiOGgHF4HKoerQPIi8D^v#;y82w_6N<#WE%u-4S> zJ@yMD$k9o7+yN`zB^IS|b=8uMZ|ydWS0eW=Ukv8FFA9WrT1PgSzpIaukrE(iY{kQs zwm2WO=KRbO(9oVI4AXt?YqyE~%!f#;{3>wHEGO^Gkm4>2EA7qWFG<$Vf=E3RE{ATA z@G(*b)2B$Muhv9@#@n1o45*Qv@BxLv$%1Q6w(5f-N*H?L_3|%XP($_Smo#m?mleZ^ z77p7b7~)ii#~p;BD5n>Ia$IV z|MFr2?&_yb4=2`k@M_-2Bk^oDh!o(16R+(L6=43%czuEW!xZ{*Eu-^0CG}FPhxxG+5)*!8ffEP?MH+Et;mKKan_Uz!twA*C~Q58I9$g&c%`33+SjwaYN+ja9d+GciQ zrRuGe+P^&P5=)=4WTiXSG!Cznl62VWU+gq?(^JllyN%W-do=%`Krw*TUN2=8F#26P zM8BkeY?$v(L_J<<_oPVHvPaO-by-W~6x}-);4g))618dDzI(4G`Ql~tyS>_N5`@iH zw6AOyMxNY``u0y=rI>T)`ppvz{e46ji;-O}RZJ=SQ-3wSobl(6LqE%xbK0}Ustp+$ zl{xzbQa8P)S&N5Tl*i}K{|KR|pQqcb^L+sASBljCk=|~;%kk**{JwpBFSSN306CYS zU}ddX-sHFAGdYE!&m6>jQaW72N>LJcDZ$$-iHf=8+7tL!XfCP;0wg;F;h>fUjhj*} zUt!zn&Va?|B=tj-T*Q1Y0tr<(C2@7x_2HImZxM!9ENueSvk(jrJ@$A0tS?u8FFKE3 ziA@nHv_>&W(D~zsC$!DW&xvE*OnvUi5@w(`ljat&e+llUT6S!HA@Kc}Ehycc1dRy< zdI=!t-uH*-9qa?-W)HVpXQ3FwUcC3}5EPINcy$e@LBL^as(}6q@2`!TLq84>ZdY79 zR8dtDf3%-+>Cn$q5***b7Yc;Mfj=ZpsXjfL`SH1Izt8(N;NNIr4%$ZGsP*ziju?IBH*BtEndXN$5NOtq1vqXZ_v##vX)#>+9hA zmcwf?{N5mBJ4s!MS{RjC|Ho*x6y^@+zFU{0klqT{7ns>v6dp}MIUT2EEq0l2(e^YQ z)GvA%UxR6w<-Cz^Z|}PIxrMcBE4mKI28mI~5PPkkKYb|lG^$nErjKFwDB(d3xXuyL z1Pys}r}UeWy6$@uI(L^3DfEz56e&Z))6jX_rack|N!jfC=xPZ`xHDM(TE9*id6>=P z;ljq=(v5jvs@44?oP@>8V*K!evi{g~XRE9`0zZBq@Z|}6yp;(HswPGC>f5g;z{j7~ za*jIAe|A$#R&bc2%**rvK}A;9yyaUaKZnhCoD#UTpGeFo#`ytO;3yiJPYfdWZL|1` zoWr8ExNbGJPZxg3Myvtrl`b&qmuo&zbbDMiagAL-aM9EH#0D5QkIhgShmGM+DK0H> z_oiEq4{^jL`oj4A#h}E*#K(=dsZWlJh-T=;9QjM{=}Z8UAbG|5TBUu?;rq}0pF&=h zwXKdB38+?Y;H&=ZX9HX7^jMBIrq`!Qn)PCg>jTEe24*PK<%XEih3kXt_4eKoy?3+W z#+~)x5gaw{7y}4EFBbcQC~mrLT`@mn$ynYHcX2ZW-2#Sk_pZ~PS6|f7)8nL?SI_SD zQKv(1$;xs^7p5*e&&pduJLm)*BlTdRPBVivkkfe2?*&4+ndM>8P^N^`c?v zabfFf{z6@S0TqH1o7MiHw=N0%%?$+3=f4Gzs?B|5_Qd&6xQ{AWEty>hFv9sh*sqN`@2lOm%=r4rUbhYZ%<2v0R;MRBiF#I z+iP0mC8YD#>IXORlD(IJh9^U~F1VK_%^da=5VfUKzkJC_zfLxRptY{_@0^fBneX-n zgKuna`>RU1t-V|Gn|DcA2w;04!Tz*tD)pY0thj8K9)o`#Ia#tCY2rdpI6i86ZsxsIHeKMeIWPM{`0-1fW{)BOnC`DN zr)YI*8H~AT?Xnsj_NKj}Mq+i#K8;#R!?YC$Vo10y=g`b@u6`w>XoRuHi80j$FL}dY z*B5Q3vhCHmol0#D>&fLUmw%mdx4)OfHU7efW-f>XorSVy3a*WY_>fX_%V#rRzuDt4 zj^+ne1W2N;1QFoj@pA7A{C~44eSUARxtxyHy!ZSpBDxKam=3kwS39P@ai?^%-ORFA zU+jBl+Z8=_aQvVZm7&7Mln5NlYvJTNct!m{8}sb_w>D{~e}DJ4_`AH;uElFMC9Sx# zGswx|&6=qbXI@-hc<02&^K;C8ZrMKf;1t^z*C*WGyg{E8*eDVaNpu!va$Pv#^Mhx# zmA|>Tmy3#s>T2lOTAhCW*?X4wO4gRI(GyOK0++wuWIfE@TT%S!M{t;mO6nVl+w-$7 zE>~RnIsrIvBp|@5pv;-d(c!(~&E0B~tt+;rJ-N8)Q*i&3spmDC!sN87XS@FWWy_H@OF44SvGQ=&sp1zmbQpj4xIYzexg-K~-?BT6 zXHGae%;DU>e^yNBQFo!$S*wFzNxe3{)7zVww_bhk#k&)3zR2{-`miII>0m<9mX;q{*?B%iY){UMHT^6LPpZtYZPE-$+-jvQQjmvvqEcso0 Q7IZ+2r>mdKI;Vst0QT?T*8l(j literal 0 HcmV?d00001 diff --git a/web/assets/index-282247e3.css b/web/assets/index-282247e3.css new file mode 100644 index 00000000..a09a9f0b --- /dev/null +++ b/web/assets/index-282247e3.css @@ -0,0 +1 @@ +*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.absolute{position:absolute}.relative{position:relative}.bottom-0{bottom:0}.left-0{left:0}.right-4{right:1rem}.top-4{top:1rem}.z-\[9999\]{z-index:9999}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mt-1{margin-top:.25rem}.inline-block{display:inline-block}.flex{display:flex}.hidden{display:none}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-4{height:1rem}.min-h-screen{min-height:100vh}.w-2{width:.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.min-w-\[300px\]{min-width:300px}.flex-1{flex:1 1 0%}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-end{align-items:flex-end}.items-center{align-items:center}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-3{row-gap:.75rem}.overflow-hidden{overflow:hidden}.whitespace-nowrap{white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-sm{border-radius:.125rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-gray-400{--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity))}.border-transparent{border-color:transparent}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity))}.bg-gray-400\/50{background-color:#9ca3af80}.bg-green-400{--tw-bg-opacity: 1;background-color:rgb(74 222 128 / var(--tw-bg-opacity))}.bg-orange-300{--tw-bg-opacity: 1;background-color:rgb(253 186 116 / var(--tw-bg-opacity))}.bg-red-300{--tw-bg-opacity: 1;background-color:rgb(252 165 165 / var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.p-2{padding:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.text-center{text-align:center}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity))}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.hover\:border-gray-400:hover{--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity))}.hover\:bg-white:hover{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.group:hover .group-hover\:block{display:block}@media (min-width: 640px){.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}} diff --git a/web/assets/index-982ea826.js b/web/assets/index-982ea826.js new file mode 100644 index 00000000..2cfe3cb4 --- /dev/null +++ b/web/assets/index-982ea826.js @@ -0,0 +1 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))r(n);new MutationObserver(n=>{for(const o of n)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&r(l)}).observe(document,{childList:!0,subtree:!0});function s(n){const o={};return n.integrity&&(o.integrity=n.integrity),n.referrerPolicy&&(o.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?o.credentials="include":n.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(n){if(n.ep)return;n.ep=!0;const o=s(n);fetch(n.href,o)}})();function Is(e,t){const s=Object.create(null),r=e.split(",");for(let n=0;n!!s[n.toLowerCase()]:n=>!!s[n]}const K={},Qe=[],be=()=>{},Fr=()=>!1,Ar=/^on[^a-z]/,zt=e=>Ar.test(e),Ms=e=>e.startsWith("onUpdate:"),G=Object.assign,Fs=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$r=Object.prototype.hasOwnProperty,S=(e,t)=>$r.call(e,t),P=Array.isArray,Ge=e=>qt(e)==="[object Map]",$n=e=>qt(e)==="[object Set]",M=e=>typeof e=="function",V=e=>typeof e=="string",As=e=>typeof e=="symbol",W=e=>e!==null&&typeof e=="object",Rn=e=>W(e)&&M(e.then)&&M(e.catch),Sn=Object.prototype.toString,qt=e=>Sn.call(e),Rr=e=>qt(e).slice(8,-1),jn=e=>qt(e)==="[object Object]",$s=e=>V(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Bt=Is(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Yt=e=>{const t=Object.create(null);return s=>t[s]||(t[s]=e(s))},Sr=/-(\w)/g,st=Yt(e=>e.replace(Sr,(t,s)=>s?s.toUpperCase():"")),jr=/\B([A-Z])/g,lt=Yt(e=>e.replace(jr,"-$1").toLowerCase()),Nn=Yt(e=>e.charAt(0).toUpperCase()+e.slice(1)),ls=Yt(e=>e?`on${Nn(e)}`:""),bt=(e,t)=>!Object.is(e,t),is=(e,t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:s})},Nr=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let tn;const gs=()=>tn||(tn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Jt(e){if(P(e)){const t={};for(let s=0;s{if(s){const r=s.split(Dr);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function it(e){let t="";if(V(e))t=e;else if(P(e))for(let s=0;sV(e)?e:e==null?"":P(e)||W(e)&&(e.toString===Sn||!M(e.toString))?JSON.stringify(e,Dn,2):String(e),Dn=(e,t)=>t&&t.__v_isRef?Dn(e,t.value):Ge(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[r,n])=>(s[`${r} =>`]=n,s),{})}:$n(t)?{[`Set(${t.size})`]:[...t.values()]}:W(t)&&!P(t)&&!jn(t)?String(t):t;let _e;class kr{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=_e,!t&&_e&&(this.index=(_e.scopes||(_e.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const s=_e;try{return _e=this,t()}finally{_e=s}}}on(){_e=this}off(){_e=this.parent}stop(t){if(this._active){let s,r;for(s=0,r=this.effects.length;s{const t=new Set(e);return t.w=0,t.n=0,t},Hn=e=>(e.w&Ne)>0,Ln=e=>(e.n&Ne)>0,qr=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let s=0;for(let r=0;r{(g==="length"||g>=u)&&c.push(a)})}else switch(s!==void 0&&c.push(l.get(s)),t){case"add":P(e)?$s(s)&&c.push(l.get("length")):(c.push(l.get(qe)),Ge(e)&&c.push(l.get(vs)));break;case"delete":P(e)||(c.push(l.get(qe)),Ge(e)&&c.push(l.get(vs)));break;case"set":Ge(e)&&c.push(l.get(qe));break}if(c.length===1)c[0]&&bs(c[0]);else{const u=[];for(const a of c)a&&u.push(...a);bs(Rs(u))}}function bs(e,t){const s=P(e)?e:[...e];for(const r of s)r.computed&&nn(r);for(const r of s)r.computed||nn(r)}function nn(e,t){(e!==me||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}const Jr=Is("__proto__,__v_isRef,__isVue"),kn=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(As)),Zr=js(),Vr=js(!1,!0),Xr=js(!0),rn=Qr();function Qr(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...s){const r=N(this);for(let o=0,l=this.length;o{e[t]=function(...s){ct();const r=N(this)[t].apply(this,s);return ft(),r}}),e}function Gr(e){const t=N(this);return ae(t,"has",e),t.hasOwnProperty(e)}function js(e=!1,t=!1){return function(r,n,o){if(n==="__v_isReactive")return!e;if(n==="__v_isReadonly")return e;if(n==="__v_isShallow")return t;if(n==="__v_raw"&&o===(e?t?_o:Jn:t?Yn:qn).get(r))return r;const l=P(r);if(!e){if(l&&S(rn,n))return Reflect.get(rn,n,o);if(n==="hasOwnProperty")return Gr}const c=Reflect.get(r,n,o);return(As(n)?kn.has(n):Jr(n))||(e||ae(r,"get",n),t)?c:le(c)?l&&$s(n)?c:c.value:W(c)?e?Zn(c):Ds(c):c}}const eo=Wn(),to=Wn(!0);function Wn(e=!1){return function(s,r,n,o){let l=s[r];if(nt(l)&&le(l)&&!le(n))return!1;if(!e&&(!Ut(n)&&!nt(n)&&(l=N(l),n=N(n)),!P(s)&&le(l)&&!le(n)))return l.value=n,!0;const c=P(s)&&$s(r)?Number(r)e,Zt=e=>Reflect.getPrototypeOf(e);function Ft(e,t,s=!1,r=!1){e=e.__v_raw;const n=N(e),o=N(t);s||(t!==o&&ae(n,"get",t),ae(n,"get",o));const{has:l}=Zt(n),c=r?Ns:s?Ls:yt;if(l.call(n,t))return c(e.get(t));if(l.call(n,o))return c(e.get(o));e!==n&&e.get(t)}function At(e,t=!1){const s=this.__v_raw,r=N(s),n=N(e);return t||(e!==n&&ae(r,"has",e),ae(r,"has",n)),e===n?s.has(e):s.has(e)||s.has(n)}function $t(e,t=!1){return e=e.__v_raw,!t&&ae(N(e),"iterate",qe),Reflect.get(e,"size",e)}function on(e){e=N(e);const t=N(this);return Zt(t).has.call(t,e)||(t.add(e),Me(t,"add",e,e)),this}function ln(e,t){t=N(t);const s=N(this),{has:r,get:n}=Zt(s);let o=r.call(s,e);o||(e=N(e),o=r.call(s,e));const l=n.call(s,e);return s.set(e,t),o?bt(t,l)&&Me(s,"set",e,t):Me(s,"add",e,t),this}function cn(e){const t=N(this),{has:s,get:r}=Zt(t);let n=s.call(t,e);n||(e=N(e),n=s.call(t,e)),r&&r.call(t,e);const o=t.delete(e);return n&&Me(t,"delete",e,void 0),o}function fn(){const e=N(this),t=e.size!==0,s=e.clear();return t&&Me(e,"clear",void 0,void 0),s}function Rt(e,t){return function(r,n){const o=this,l=o.__v_raw,c=N(l),u=t?Ns:e?Ls:yt;return!e&&ae(c,"iterate",qe),l.forEach((a,g)=>r.call(n,u(a),u(g),o))}}function St(e,t,s){return function(...r){const n=this.__v_raw,o=N(n),l=Ge(o),c=e==="entries"||e===Symbol.iterator&&l,u=e==="keys"&&l,a=n[e](...r),g=s?Ns:t?Ls:yt;return!t&&ae(o,"iterate",u?vs:qe),{next(){const{value:x,done:E}=a.next();return E?{value:x,done:E}:{value:c?[g(x[0]),g(x[1])]:g(x),done:E}},[Symbol.iterator](){return this}}}}function $e(e){return function(...t){return e==="delete"?!1:this}}function io(){const e={get(o){return Ft(this,o)},get size(){return $t(this)},has:At,add:on,set:ln,delete:cn,clear:fn,forEach:Rt(!1,!1)},t={get(o){return Ft(this,o,!1,!0)},get size(){return $t(this)},has:At,add:on,set:ln,delete:cn,clear:fn,forEach:Rt(!1,!0)},s={get(o){return Ft(this,o,!0)},get size(){return $t(this,!0)},has(o){return At.call(this,o,!0)},add:$e("add"),set:$e("set"),delete:$e("delete"),clear:$e("clear"),forEach:Rt(!0,!1)},r={get(o){return Ft(this,o,!0,!0)},get size(){return $t(this,!0)},has(o){return At.call(this,o,!0)},add:$e("add"),set:$e("set"),delete:$e("delete"),clear:$e("clear"),forEach:Rt(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=St(o,!1,!1),s[o]=St(o,!0,!1),t[o]=St(o,!1,!0),r[o]=St(o,!0,!0)}),[e,s,t,r]}const[co,fo,uo,ao]=io();function Bs(e,t){const s=t?e?ao:uo:e?fo:co;return(r,n,o)=>n==="__v_isReactive"?!e:n==="__v_isReadonly"?e:n==="__v_raw"?r:Reflect.get(S(s,n)&&n in r?s:r,n,o)}const ho={get:Bs(!1,!1)},po={get:Bs(!1,!0)},go={get:Bs(!0,!1)},qn=new WeakMap,Yn=new WeakMap,Jn=new WeakMap,_o=new WeakMap;function mo(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function vo(e){return e.__v_skip||!Object.isExtensible(e)?0:mo(Rr(e))}function Ds(e){return nt(e)?e:Hs(e,!1,zn,ho,qn)}function bo(e){return Hs(e,!1,lo,po,Yn)}function Zn(e){return Hs(e,!0,oo,go,Jn)}function Hs(e,t,s,r,n){if(!W(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=n.get(e);if(o)return o;const l=vo(e);if(l===0)return e;const c=new Proxy(e,l===2?r:s);return n.set(e,c),c}function et(e){return nt(e)?et(e.__v_raw):!!(e&&e.__v_isReactive)}function nt(e){return!!(e&&e.__v_isReadonly)}function Ut(e){return!!(e&&e.__v_isShallow)}function Vn(e){return et(e)||nt(e)}function N(e){const t=e&&e.__v_raw;return t?N(t):e}function Xn(e){return Lt(e,"__v_skip",!0),e}const yt=e=>W(e)?Ds(e):e,Ls=e=>W(e)?Zn(e):e;function Qn(e){Se&&me&&(e=N(e),Kn(e.dep||(e.dep=Rs())))}function Gn(e,t){e=N(e);const s=e.dep;s&&bs(s)}function le(e){return!!(e&&e.__v_isRef===!0)}function jt(e){return yo(e,!1)}function yo(e,t){return le(e)?e:new xo(e,t)}class xo{constructor(t,s){this.__v_isShallow=s,this.dep=void 0,this.__v_isRef=!0,this._rawValue=s?t:N(t),this._value=s?t:yt(t)}get value(){return Qn(this),this._value}set value(t){const s=this.__v_isShallow||Ut(t)||nt(t);t=s?t:N(t),bt(t,this._rawValue)&&(this._rawValue=t,this._value=s?t:yt(t),Gn(this))}}function U(e){return le(e)?e.value:e}const wo={get:(e,t,s)=>U(Reflect.get(e,t,s)),set:(e,t,s,r)=>{const n=e[t];return le(n)&&!le(s)?(n.value=s,!0):Reflect.set(e,t,s,r)}};function er(e){return et(e)?e:new Proxy(e,wo)}class Eo{constructor(t,s,r,n){this._setter=s,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new Ss(t,()=>{this._dirty||(this._dirty=!0,Gn(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!n,this.__v_isReadonly=r}get value(){const t=N(this);return Qn(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function Co(e,t,s=!1){let r,n;const o=M(e);return o?(r=e,n=be):(r=e.get,n=e.set),new Eo(r,n,o||!n,s)}function je(e,t,s,r){let n;try{n=r?e(...r):e()}catch(o){Vt(o,t,s)}return n}function ye(e,t,s,r){if(M(e)){const o=je(e,t,s,r);return o&&Rn(o)&&o.catch(l=>{Vt(l,t,s)}),o}const n=[];for(let o=0;o>>1;wt(re[r])Te&&re.splice(t,1)}function Mo(e){P(e)?tt.push(...e):(!Ie||!Ie.includes(e,e.allowRecurse?We+1:We))&&tt.push(e),sr()}function un(e,t=xt?Te+1:0){for(;twt(s)-wt(r)),We=0;Wee.id==null?1/0:e.id,Fo=(e,t)=>{const s=wt(e)-wt(t);if(s===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return s};function rr(e){ys=!1,xt=!0,re.sort(Fo);const t=be;try{for(Te=0;TeV(I)?I.trim():I)),x&&(n=s.map(Nr))}let c,u=r[c=ls(t)]||r[c=ls(st(t))];!u&&o&&(u=r[c=ls(lt(t))]),u&&ye(u,e,6,n);const a=r[c+"Once"];if(a){if(!e.emitted)e.emitted={};else if(e.emitted[c])return;e.emitted[c]=!0,ye(a,e,6,n)}}function or(e,t,s=!1){const r=t.emitsCache,n=r.get(e);if(n!==void 0)return n;const o=e.emits;let l={},c=!1;if(!M(e)){const u=a=>{const g=or(a,t,!0);g&&(c=!0,G(l,g))};!s&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}return!o&&!c?(W(e)&&r.set(e,null),null):(P(o)?o.forEach(u=>l[u]=null):G(l,o),W(e)&&r.set(e,l),l)}function Xt(e,t){return!e||!zt(t)?!1:(t=t.slice(2).replace(/Once$/,""),S(e,t[0].toLowerCase()+t.slice(1))||S(e,lt(t))||S(e,t))}let ue=null,lr=null;function Kt(e){const t=ue;return ue=e,lr=e&&e.type.__scopeId||null,t}function Q(e,t=ue,s){if(!t||e._n)return e;const r=(...n)=>{r._d&&yn(-1);const o=Kt(t);let l;try{l=e(...n)}finally{Kt(o),r._d&&yn(1)}return l};return r._n=!0,r._c=!0,r._d=!0,r}function cs(e){const{type:t,vnode:s,proxy:r,withProxy:n,props:o,propsOptions:[l],slots:c,attrs:u,emit:a,render:g,renderCache:x,data:E,setupState:I,ctx:Y,inheritAttrs:$}=e;let X,te;const se=Kt(e);try{if(s.shapeFlag&4){const F=n||r;X=Oe(g.call(F,F,x,o,I,E,Y)),te=u}else{const F=t;X=Oe(F.length>1?F(o,{attrs:u,slots:c,emit:a}):F(o,null)),te=t.props?u:$o(u)}}catch(F){vt.length=0,Vt(F,e,1),X=L(Be)}let ne=X;if(te&&$!==!1){const F=Object.keys(te),{shapeFlag:Ae}=ne;F.length&&Ae&7&&(l&&F.some(Ms)&&(te=Ro(te,l)),ne=rt(ne,te))}return s.dirs&&(ne=rt(ne),ne.dirs=ne.dirs?ne.dirs.concat(s.dirs):s.dirs),s.transition&&(ne.transition=s.transition),X=ne,Kt(se),X}const $o=e=>{let t;for(const s in e)(s==="class"||s==="style"||zt(s))&&((t||(t={}))[s]=e[s]);return t},Ro=(e,t)=>{const s={};for(const r in e)(!Ms(r)||!(r.slice(9)in t))&&(s[r]=e[r]);return s};function So(e,t,s){const{props:r,children:n,component:o}=e,{props:l,children:c,patchFlag:u}=t,a=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&u>=0){if(u&1024)return!0;if(u&16)return r?an(r,l,a):!!l;if(u&8){const g=t.dynamicProps;for(let x=0;xe.__isSuspense;function Bo(e,t){t&&t.pendingBranch?P(e)?t.effects.push(...e):t.effects.push(e):Mo(e)}const Nt={};function fs(e,t,s){return ir(e,t,s)}function ir(e,t,{immediate:s,deep:r,flush:n,onTrack:o,onTrigger:l}=K){var c;const u=zr()===((c=oe)==null?void 0:c.scope)?oe:null;let a,g=!1,x=!1;if(le(e)?(a=()=>e.value,g=Ut(e)):et(e)?(a=()=>e,r=!0):P(e)?(x=!0,g=e.some(F=>et(F)||Ut(F)),a=()=>e.map(F=>{if(le(F))return F.value;if(et(F))return Xe(F);if(M(F))return je(F,u,2)})):M(e)?t?a=()=>je(e,u,2):a=()=>{if(!(u&&u.isUnmounted))return E&&E(),ye(e,u,3,[I])}:a=be,t&&r){const F=a;a=()=>Xe(F())}let E,I=F=>{E=se.onStop=()=>{je(F,u,4)}},Y;if(Ct)if(I=be,t?s&&ye(t,u,3,[a(),x?[]:void 0,I]):a(),n==="sync"){const F=Ml();Y=F.__watcherHandles||(F.__watcherHandles=[])}else return be;let $=x?new Array(e.length).fill(Nt):Nt;const X=()=>{if(se.active)if(t){const F=se.run();(r||g||(x?F.some((Ae,ut)=>bt(Ae,$[ut])):bt(F,$)))&&(E&&E(),ye(t,u,3,[F,$===Nt?void 0:x&&$[0]===Nt?[]:$,I]),$=F)}else se.run()};X.allowRecurse=!!t;let te;n==="sync"?te=X:n==="post"?te=()=>fe(X,u&&u.suspense):(X.pre=!0,u&&(X.id=u.uid),te=()=>Ks(X));const se=new Ss(a,te);t?s?X():$=se.run():n==="post"?fe(se.run.bind(se),u&&u.suspense):se.run();const ne=()=>{se.stop(),u&&u.scope&&Fs(u.scope.effects,se)};return Y&&Y.push(ne),ne}function Do(e,t,s){const r=this.proxy,n=V(e)?e.includes(".")?cr(r,e):()=>r[e]:e.bind(r,r);let o;M(t)?o=t:(o=t.handler,s=t);const l=oe;ot(this);const c=ir(n,o.bind(r),s);return l?ot(l):Ye(),c}function cr(e,t){const s=t.split(".");return()=>{let r=e;for(let n=0;n{Xe(s,t)});else if(jn(e))for(const s in e)Xe(e[s],t);return e}function Ke(e,t,s,r){const n=e.dirs,o=t&&t.dirs;for(let l=0;lG({name:e.name},t,{setup:e}))():e}const _t=e=>!!e.type.__asyncLoader,fr=e=>e.type.__isKeepAlive;function Ho(e,t){ur(e,"a",t)}function Lo(e,t){ur(e,"da",t)}function ur(e,t,s=oe){const r=e.__wdc||(e.__wdc=()=>{let n=s;for(;n;){if(n.isDeactivated)return;n=n.parent}return e()});if(Gt(t,r,s),s){let n=s.parent;for(;n&&n.parent;)fr(n.parent.vnode)&&Uo(r,t,s,n),n=n.parent}}function Uo(e,t,s,r){const n=Gt(t,e,r,!0);dr(()=>{Fs(r[t],n)},s)}function Gt(e,t,s=oe,r=!1){if(s){const n=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...l)=>{if(s.isUnmounted)return;ct(),ot(s);const c=ye(t,s,e,l);return Ye(),ft(),c});return r?n.unshift(o):n.push(o),o}}const Fe=e=>(t,s=oe)=>(!Ct||e==="sp")&&Gt(e,(...r)=>t(...r),s),Ko=Fe("bm"),ar=Fe("m"),ko=Fe("bu"),Wo=Fe("u"),zo=Fe("bum"),dr=Fe("um"),qo=Fe("sp"),Yo=Fe("rtg"),Jo=Fe("rtc");function Zo(e,t=oe){Gt("ec",e,t)}const Vo=Symbol.for("v-ndc");function Xo(e,t,s,r){let n;const o=s&&s[r];if(P(e)||V(e)){n=new Array(e.length);for(let l=0,c=e.length;lt(l,c,void 0,o&&o[c]));else{const l=Object.keys(e);n=new Array(l.length);for(let c=0,u=l.length;cCr(t)?!(t.type===Be||t.type===he&&!pr(t.children)):!0)?e:null}const xs=e=>e?Tr(e)?Ys(e)||e.proxy:xs(e.parent):null,mt=G(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>xs(e.parent),$root:e=>xs(e.root),$emit:e=>e.emit,$options:e=>ks(e),$forceUpdate:e=>e.f||(e.f=()=>Ks(e.update)),$nextTick:e=>e.n||(e.n=To.bind(e.proxy)),$watch:e=>Do.bind(e)}),us=(e,t)=>e!==K&&!e.__isScriptSetup&&S(e,t),Qo={get({_:e},t){const{ctx:s,setupState:r,data:n,props:o,accessCache:l,type:c,appContext:u}=e;let a;if(t[0]!=="$"){const I=l[t];if(I!==void 0)switch(I){case 1:return r[t];case 2:return n[t];case 4:return s[t];case 3:return o[t]}else{if(us(r,t))return l[t]=1,r[t];if(n!==K&&S(n,t))return l[t]=2,n[t];if((a=e.propsOptions[0])&&S(a,t))return l[t]=3,o[t];if(s!==K&&S(s,t))return l[t]=4,s[t];ws&&(l[t]=0)}}const g=mt[t];let x,E;if(g)return t==="$attrs"&&ae(e,"get",t),g(e);if((x=c.__cssModules)&&(x=x[t]))return x;if(s!==K&&S(s,t))return l[t]=4,s[t];if(E=u.config.globalProperties,S(E,t))return E[t]},set({_:e},t,s){const{data:r,setupState:n,ctx:o}=e;return us(n,t)?(n[t]=s,!0):r!==K&&S(r,t)?(r[t]=s,!0):S(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:r,appContext:n,propsOptions:o}},l){let c;return!!s[l]||e!==K&&S(e,l)||us(t,l)||(c=o[0])&&S(c,l)||S(r,l)||S(mt,l)||S(n.config.globalProperties,l)},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:S(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function dn(e){return P(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let ws=!0;function Go(e){const t=ks(e),s=e.proxy,r=e.ctx;ws=!1,t.beforeCreate&&hn(t.beforeCreate,e,"bc");const{data:n,computed:o,methods:l,watch:c,provide:u,inject:a,created:g,beforeMount:x,mounted:E,beforeUpdate:I,updated:Y,activated:$,deactivated:X,beforeDestroy:te,beforeUnmount:se,destroyed:ne,unmounted:F,render:Ae,renderTracked:ut,renderTriggered:Ot,errorCaptured:De,serverPrefetch:ss,expose:He,inheritAttrs:at,components:Tt,directives:Pt,filters:ns}=t;if(a&&el(a,r,null),l)for(const z in l){const D=l[z];M(D)&&(r[z]=D.bind(s))}if(n){const z=n.call(s,s);W(z)&&(e.data=Ds(z))}if(ws=!0,o)for(const z in o){const D=o[z],Le=M(D)?D.bind(s,s):M(D.get)?D.get.bind(s,s):be,It=!M(D)&&M(D.set)?D.set.bind(s):be,Ue=Ts({get:Le,set:It});Object.defineProperty(r,z,{enumerable:!0,configurable:!0,get:()=>Ue.value,set:xe=>Ue.value=xe})}if(c)for(const z in c)gr(c[z],r,s,z);if(u){const z=M(u)?u.call(s):u;Reflect.ownKeys(z).forEach(D=>{ll(D,z[D])})}g&&hn(g,e,"c");function ie(z,D){P(D)?D.forEach(Le=>z(Le.bind(s))):D&&z(D.bind(s))}if(ie(Ko,x),ie(ar,E),ie(ko,I),ie(Wo,Y),ie(Ho,$),ie(Lo,X),ie(Zo,De),ie(Jo,ut),ie(Yo,Ot),ie(zo,se),ie(dr,F),ie(qo,ss),P(He))if(He.length){const z=e.exposed||(e.exposed={});He.forEach(D=>{Object.defineProperty(z,D,{get:()=>s[D],set:Le=>s[D]=Le})})}else e.exposed||(e.exposed={});Ae&&e.render===be&&(e.render=Ae),at!=null&&(e.inheritAttrs=at),Tt&&(e.components=Tt),Pt&&(e.directives=Pt)}function el(e,t,s=be){P(e)&&(e=Es(e));for(const r in e){const n=e[r];let o;W(n)?"default"in n?o=Dt(n.from||r,n.default,!0):o=Dt(n.from||r):o=Dt(n),le(o)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>o.value,set:l=>o.value=l}):t[r]=o}}function hn(e,t,s){ye(P(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,s)}function gr(e,t,s,r){const n=r.includes(".")?cr(s,r):()=>s[r];if(V(e)){const o=t[e];M(o)&&fs(n,o)}else if(M(e))fs(n,e.bind(s));else if(W(e))if(P(e))e.forEach(o=>gr(o,t,s,r));else{const o=M(e.handler)?e.handler.bind(s):t[e.handler];M(o)&&fs(n,o,e)}}function ks(e){const t=e.type,{mixins:s,extends:r}=t,{mixins:n,optionsCache:o,config:{optionMergeStrategies:l}}=e.appContext,c=o.get(t);let u;return c?u=c:!n.length&&!s&&!r?u=t:(u={},n.length&&n.forEach(a=>kt(u,a,l,!0)),kt(u,t,l)),W(t)&&o.set(t,u),u}function kt(e,t,s,r=!1){const{mixins:n,extends:o}=t;o&&kt(e,o,s,!0),n&&n.forEach(l=>kt(e,l,s,!0));for(const l in t)if(!(r&&l==="expose")){const c=tl[l]||s&&s[l];e[l]=c?c(e[l],t[l]):t[l]}return e}const tl={data:pn,props:gn,emits:gn,methods:gt,computed:gt,beforeCreate:ce,created:ce,beforeMount:ce,mounted:ce,beforeUpdate:ce,updated:ce,beforeDestroy:ce,beforeUnmount:ce,destroyed:ce,unmounted:ce,activated:ce,deactivated:ce,errorCaptured:ce,serverPrefetch:ce,components:gt,directives:gt,watch:nl,provide:pn,inject:sl};function pn(e,t){return t?e?function(){return G(M(e)?e.call(this,this):e,M(t)?t.call(this,this):t)}:t:e}function sl(e,t){return gt(Es(e),Es(t))}function Es(e){if(P(e)){const t={};for(let s=0;s1)return s&&M(t)?t.call(r&&r.proxy):t}}function il(e,t,s,r=!1){const n={},o={};Lt(o,ts,1),e.propsDefaults=Object.create(null),mr(e,t,n,o);for(const l in e.propsOptions[0])l in n||(n[l]=void 0);s?e.props=r?n:bo(n):e.type.props?e.props=n:e.props=o,e.attrs=o}function cl(e,t,s,r){const{props:n,attrs:o,vnode:{patchFlag:l}}=e,c=N(n),[u]=e.propsOptions;let a=!1;if((r||l>0)&&!(l&16)){if(l&8){const g=e.vnode.dynamicProps;for(let x=0;x{u=!0;const[E,I]=vr(x,t,!0);G(l,E),I&&c.push(...I)};!s&&t.mixins.length&&t.mixins.forEach(g),e.extends&&g(e.extends),e.mixins&&e.mixins.forEach(g)}if(!o&&!u)return W(e)&&r.set(e,Qe),Qe;if(P(o))for(let g=0;g-1,I[1]=$<0||Y<$,(Y>-1||S(I,"default"))&&c.push(x)}}}const a=[l,c];return W(e)&&r.set(e,a),a}function _n(e){return e[0]!=="$"}function mn(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function vn(e,t){return mn(e)===mn(t)}function bn(e,t){return P(t)?t.findIndex(s=>vn(s,e)):M(t)&&vn(t,e)?0:-1}const br=e=>e[0]==="_"||e==="$stable",Ws=e=>P(e)?e.map(Oe):[Oe(e)],fl=(e,t,s)=>{if(t._n)return t;const r=Q((...n)=>Ws(t(...n)),s);return r._c=!1,r},yr=(e,t,s)=>{const r=e._ctx;for(const n in e){if(br(n))continue;const o=e[n];if(M(o))t[n]=fl(n,o,r);else if(o!=null){const l=Ws(o);t[n]=()=>l}}},xr=(e,t)=>{const s=Ws(t);e.slots.default=()=>s},ul=(e,t)=>{if(e.vnode.shapeFlag&32){const s=t._;s?(e.slots=N(t),Lt(t,"_",s)):yr(t,e.slots={})}else e.slots={},t&&xr(e,t);Lt(e.slots,ts,1)},al=(e,t,s)=>{const{vnode:r,slots:n}=e;let o=!0,l=K;if(r.shapeFlag&32){const c=t._;c?s&&c===1?o=!1:(G(n,t),!s&&c===1&&delete n._):(o=!t.$stable,yr(t,n)),l=t}else t&&(xr(e,t),l={default:1});if(o)for(const c in n)!br(c)&&!(c in l)&&delete n[c]};function Os(e,t,s,r,n=!1){if(P(e)){e.forEach((E,I)=>Os(E,t&&(P(t)?t[I]:t),s,r,n));return}if(_t(r)&&!n)return;const o=r.shapeFlag&4?Ys(r.component)||r.component.proxy:r.el,l=n?null:o,{i:c,r:u}=e,a=t&&t.r,g=c.refs===K?c.refs={}:c.refs,x=c.setupState;if(a!=null&&a!==u&&(V(a)?(g[a]=null,S(x,a)&&(x[a]=null)):le(a)&&(a.value=null)),M(u))je(u,c,12,[l,g]);else{const E=V(u),I=le(u);if(E||I){const Y=()=>{if(e.f){const $=E?S(x,u)?x[u]:g[u]:u.value;n?P($)&&Fs($,o):P($)?$.includes(o)||$.push(o):E?(g[u]=[o],S(x,u)&&(x[u]=g[u])):(u.value=[o],e.k&&(g[e.k]=u.value))}else E?(g[u]=l,S(x,u)&&(x[u]=l)):I&&(u.value=l,e.k&&(g[e.k]=l))};l?(Y.id=-1,fe(Y,s)):Y()}}}const fe=Bo;function dl(e){return hl(e)}function hl(e,t){const s=gs();s.__VUE__=!0;const{insert:r,remove:n,patchProp:o,createElement:l,createText:c,createComment:u,setText:a,setElementText:g,parentNode:x,nextSibling:E,setScopeId:I=be,insertStaticContent:Y}=e,$=(i,f,d,p=null,h=null,v=null,y=!1,m=null,b=!!f.dynamicChildren)=>{if(i===f)return;i&&!ht(i,f)&&(p=Mt(i),xe(i,h,v,!0),i=null),f.patchFlag===-2&&(b=!1,f.dynamicChildren=null);const{type:_,ref:C,shapeFlag:w}=f;switch(_){case es:X(i,f,d,p);break;case Be:te(i,f,d,p);break;case as:i==null&&se(f,d,p,y);break;case he:Tt(i,f,d,p,h,v,y,m,b);break;default:w&1?Ae(i,f,d,p,h,v,y,m,b):w&6?Pt(i,f,d,p,h,v,y,m,b):(w&64||w&128)&&_.process(i,f,d,p,h,v,y,m,b,Je)}C!=null&&h&&Os(C,i&&i.ref,v,f||i,!f)},X=(i,f,d,p)=>{if(i==null)r(f.el=c(f.children),d,p);else{const h=f.el=i.el;f.children!==i.children&&a(h,f.children)}},te=(i,f,d,p)=>{i==null?r(f.el=u(f.children||""),d,p):f.el=i.el},se=(i,f,d,p)=>{[i.el,i.anchor]=Y(i.children,f,d,p,i.el,i.anchor)},ne=({el:i,anchor:f},d,p)=>{let h;for(;i&&i!==f;)h=E(i),r(i,d,p),i=h;r(f,d,p)},F=({el:i,anchor:f})=>{let d;for(;i&&i!==f;)d=E(i),n(i),i=d;n(f)},Ae=(i,f,d,p,h,v,y,m,b)=>{y=y||f.type==="svg",i==null?ut(f,d,p,h,v,y,m,b):ss(i,f,h,v,y,m,b)},ut=(i,f,d,p,h,v,y,m)=>{let b,_;const{type:C,props:w,shapeFlag:O,transition:T,dirs:A}=i;if(b=i.el=l(i.type,v,w&&w.is,w),O&8?g(b,i.children):O&16&&De(i.children,b,null,p,h,v&&C!=="foreignObject",y,m),A&&Ke(i,null,p,"created"),Ot(b,i,i.scopeId,y,p),w){for(const B in w)B!=="value"&&!Bt(B)&&o(b,B,null,w[B],v,i.children,p,h,Pe);"value"in w&&o(b,"value",null,w.value),(_=w.onVnodeBeforeMount)&&Ee(_,p,i)}A&&Ke(i,null,p,"beforeMount");const H=(!h||h&&!h.pendingBranch)&&T&&!T.persisted;H&&T.beforeEnter(b),r(b,f,d),((_=w&&w.onVnodeMounted)||H||A)&&fe(()=>{_&&Ee(_,p,i),H&&T.enter(b),A&&Ke(i,null,p,"mounted")},h)},Ot=(i,f,d,p,h)=>{if(d&&I(i,d),p)for(let v=0;v{for(let _=b;_{const m=f.el=i.el;let{patchFlag:b,dynamicChildren:_,dirs:C}=f;b|=i.patchFlag&16;const w=i.props||K,O=f.props||K;let T;d&&ke(d,!1),(T=O.onVnodeBeforeUpdate)&&Ee(T,d,f,i),C&&Ke(f,i,d,"beforeUpdate"),d&&ke(d,!0);const A=h&&f.type!=="foreignObject";if(_?He(i.dynamicChildren,_,m,d,p,A,v):y||D(i,f,m,null,d,p,A,v,!1),b>0){if(b&16)at(m,f,w,O,d,p,h);else if(b&2&&w.class!==O.class&&o(m,"class",null,O.class,h),b&4&&o(m,"style",w.style,O.style,h),b&8){const H=f.dynamicProps;for(let B=0;B{T&&Ee(T,d,f,i),C&&Ke(f,i,d,"updated")},p)},He=(i,f,d,p,h,v,y)=>{for(let m=0;m{if(d!==p){if(d!==K)for(const m in d)!Bt(m)&&!(m in p)&&o(i,m,d[m],null,y,f.children,h,v,Pe);for(const m in p){if(Bt(m))continue;const b=p[m],_=d[m];b!==_&&m!=="value"&&o(i,m,_,b,y,f.children,h,v,Pe)}"value"in p&&o(i,"value",d.value,p.value)}},Tt=(i,f,d,p,h,v,y,m,b)=>{const _=f.el=i?i.el:c(""),C=f.anchor=i?i.anchor:c("");let{patchFlag:w,dynamicChildren:O,slotScopeIds:T}=f;T&&(m=m?m.concat(T):T),i==null?(r(_,d,p),r(C,d,p),De(f.children,d,C,h,v,y,m,b)):w>0&&w&64&&O&&i.dynamicChildren?(He(i.dynamicChildren,O,d,h,v,y,m),(f.key!=null||h&&f===h.subTree)&&wr(i,f,!0)):D(i,f,d,C,h,v,y,m,b)},Pt=(i,f,d,p,h,v,y,m,b)=>{f.slotScopeIds=m,i==null?f.shapeFlag&512?h.ctx.activate(f,d,p,y,b):ns(f,d,p,h,v,y,b):Zs(i,f,b)},ns=(i,f,d,p,h,v,y)=>{const m=i.component=wl(i,p,h);if(fr(i)&&(m.ctx.renderer=Je),El(m),m.asyncDep){if(h&&h.registerDep(m,ie),!i.el){const b=m.subTree=L(Be);te(null,b,f,d)}return}ie(m,i,f,d,h,v,y)},Zs=(i,f,d)=>{const p=f.component=i.component;if(So(i,f,d))if(p.asyncDep&&!p.asyncResolved){z(p,f,d);return}else p.next=f,Io(p.update),p.update();else f.el=i.el,p.vnode=f},ie=(i,f,d,p,h,v,y)=>{const m=()=>{if(i.isMounted){let{next:C,bu:w,u:O,parent:T,vnode:A}=i,H=C,B;ke(i,!1),C?(C.el=A.el,z(i,C,y)):C=A,w&&is(w),(B=C.props&&C.props.onVnodeBeforeUpdate)&&Ee(B,T,C,A),ke(i,!0);const J=cs(i),ge=i.subTree;i.subTree=J,$(ge,J,x(ge.el),Mt(ge),i,h,v),C.el=J.el,H===null&&jo(i,J.el),O&&fe(O,h),(B=C.props&&C.props.onVnodeUpdated)&&fe(()=>Ee(B,T,C,A),h)}else{let C;const{el:w,props:O}=f,{bm:T,m:A,parent:H}=i,B=_t(f);if(ke(i,!1),T&&is(T),!B&&(C=O&&O.onVnodeBeforeMount)&&Ee(C,H,f),ke(i,!0),w&&os){const J=()=>{i.subTree=cs(i),os(w,i.subTree,i,h,null)};B?f.type.__asyncLoader().then(()=>!i.isUnmounted&&J()):J()}else{const J=i.subTree=cs(i);$(null,J,d,p,i,h,v),f.el=J.el}if(A&&fe(A,h),!B&&(C=O&&O.onVnodeMounted)){const J=f;fe(()=>Ee(C,H,J),h)}(f.shapeFlag&256||H&&_t(H.vnode)&&H.vnode.shapeFlag&256)&&i.a&&fe(i.a,h),i.isMounted=!0,f=d=p=null}},b=i.effect=new Ss(m,()=>Ks(_),i.scope),_=i.update=()=>b.run();_.id=i.uid,ke(i,!0),_()},z=(i,f,d)=>{f.component=i;const p=i.vnode.props;i.vnode=f,i.next=null,cl(i,f.props,p,d),al(i,f.children,d),ct(),un(),ft()},D=(i,f,d,p,h,v,y,m,b=!1)=>{const _=i&&i.children,C=i?i.shapeFlag:0,w=f.children,{patchFlag:O,shapeFlag:T}=f;if(O>0){if(O&128){It(_,w,d,p,h,v,y,m,b);return}else if(O&256){Le(_,w,d,p,h,v,y,m,b);return}}T&8?(C&16&&Pe(_,h,v),w!==_&&g(d,w)):C&16?T&16?It(_,w,d,p,h,v,y,m,b):Pe(_,h,v,!0):(C&8&&g(d,""),T&16&&De(w,d,p,h,v,y,m,b))},Le=(i,f,d,p,h,v,y,m,b)=>{i=i||Qe,f=f||Qe;const _=i.length,C=f.length,w=Math.min(_,C);let O;for(O=0;OC?Pe(i,h,v,!0,!1,w):De(f,d,p,h,v,y,m,b,w)},It=(i,f,d,p,h,v,y,m,b)=>{let _=0;const C=f.length;let w=i.length-1,O=C-1;for(;_<=w&&_<=O;){const T=i[_],A=f[_]=b?Re(f[_]):Oe(f[_]);if(ht(T,A))$(T,A,d,null,h,v,y,m,b);else break;_++}for(;_<=w&&_<=O;){const T=i[w],A=f[O]=b?Re(f[O]):Oe(f[O]);if(ht(T,A))$(T,A,d,null,h,v,y,m,b);else break;w--,O--}if(_>w){if(_<=O){const T=O+1,A=TO)for(;_<=w;)xe(i[_],h,v,!0),_++;else{const T=_,A=_,H=new Map;for(_=A;_<=O;_++){const de=f[_]=b?Re(f[_]):Oe(f[_]);de.key!=null&&H.set(de.key,_)}let B,J=0;const ge=O-A+1;let Ze=!1,Qs=0;const dt=new Array(ge);for(_=0;_=ge){xe(de,h,v,!0);continue}let we;if(de.key!=null)we=H.get(de.key);else for(B=A;B<=O;B++)if(dt[B-A]===0&&ht(de,f[B])){we=B;break}we===void 0?xe(de,h,v,!0):(dt[we-A]=_+1,we>=Qs?Qs=we:Ze=!0,$(de,f[we],d,null,h,v,y,m,b),J++)}const Gs=Ze?pl(dt):Qe;for(B=Gs.length-1,_=ge-1;_>=0;_--){const de=A+_,we=f[de],en=de+1{const{el:v,type:y,transition:m,children:b,shapeFlag:_}=i;if(_&6){Ue(i.component.subTree,f,d,p);return}if(_&128){i.suspense.move(f,d,p);return}if(_&64){y.move(i,f,d,Je);return}if(y===he){r(v,f,d);for(let w=0;wm.enter(v),h);else{const{leave:w,delayLeave:O,afterLeave:T}=m,A=()=>r(v,f,d),H=()=>{w(v,()=>{A(),T&&T()})};O?O(v,A,H):H()}else r(v,f,d)},xe=(i,f,d,p=!1,h=!1)=>{const{type:v,props:y,ref:m,children:b,dynamicChildren:_,shapeFlag:C,patchFlag:w,dirs:O}=i;if(m!=null&&Os(m,null,d,i,!0),C&256){f.ctx.deactivate(i);return}const T=C&1&&O,A=!_t(i);let H;if(A&&(H=y&&y.onVnodeBeforeUnmount)&&Ee(H,f,i),C&6)Mr(i.component,d,p);else{if(C&128){i.suspense.unmount(d,p);return}T&&Ke(i,null,f,"beforeUnmount"),C&64?i.type.remove(i,f,d,h,Je,p):_&&(v!==he||w>0&&w&64)?Pe(_,f,d,!1,!0):(v===he&&w&384||!h&&C&16)&&Pe(b,f,d),p&&Vs(i)}(A&&(H=y&&y.onVnodeUnmounted)||T)&&fe(()=>{H&&Ee(H,f,i),T&&Ke(i,null,f,"unmounted")},d)},Vs=i=>{const{type:f,el:d,anchor:p,transition:h}=i;if(f===he){Ir(d,p);return}if(f===as){F(i);return}const v=()=>{n(d),h&&!h.persisted&&h.afterLeave&&h.afterLeave()};if(i.shapeFlag&1&&h&&!h.persisted){const{leave:y,delayLeave:m}=h,b=()=>y(d,v);m?m(i.el,v,b):b()}else v()},Ir=(i,f)=>{let d;for(;i!==f;)d=E(i),n(i),i=d;n(f)},Mr=(i,f,d)=>{const{bum:p,scope:h,update:v,subTree:y,um:m}=i;p&&is(p),h.stop(),v&&(v.active=!1,xe(y,i,f,d)),m&&fe(m,f),fe(()=>{i.isUnmounted=!0},f),f&&f.pendingBranch&&!f.isUnmounted&&i.asyncDep&&!i.asyncResolved&&i.suspenseId===f.pendingId&&(f.deps--,f.deps===0&&f.resolve())},Pe=(i,f,d,p=!1,h=!1,v=0)=>{for(let y=v;yi.shapeFlag&6?Mt(i.component.subTree):i.shapeFlag&128?i.suspense.next():E(i.anchor||i.el),Xs=(i,f,d)=>{i==null?f._vnode&&xe(f._vnode,null,null,!0):$(f._vnode||null,i,f,null,null,null,d),un(),nr(),f._vnode=i},Je={p:$,um:xe,m:Ue,r:Vs,mt:ns,mc:De,pc:D,pbc:He,n:Mt,o:e};let rs,os;return t&&([rs,os]=t(Je)),{render:Xs,hydrate:rs,createApp:ol(Xs,rs)}}function ke({effect:e,update:t},s){e.allowRecurse=t.allowRecurse=s}function wr(e,t,s=!1){const r=e.children,n=t.children;if(P(r)&&P(n))for(let o=0;o>1,e[s[c]]0&&(t[r]=s[o-1]),s[o]=r)}}for(o=s.length,l=s[o-1];o-- >0;)s[o]=l,l=t[l];return s}const gl=e=>e.__isTeleport,he=Symbol.for("v-fgt"),es=Symbol.for("v-txt"),Be=Symbol.for("v-cmt"),as=Symbol.for("v-stc"),vt=[];let ve=null;function R(e=!1){vt.push(ve=e?null:[])}function _l(){vt.pop(),ve=vt[vt.length-1]||null}let Et=1;function yn(e){Et+=e}function Er(e){return e.dynamicChildren=Et>0?ve||Qe:null,_l(),Et>0&&ve&&ve.push(e),e}function q(e,t,s,r,n,o){return Er(ee(e,t,s,r,n,o,!0))}function pe(e,t,s,r,n){return Er(L(e,t,s,r,n,!0))}function Cr(e){return e?e.__v_isVNode===!0:!1}function ht(e,t){return e.type===t.type&&e.key===t.key}const ts="__vInternal",Or=({key:e})=>e??null,Ht=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?V(e)||le(e)||M(e)?{i:ue,r:e,k:t,f:!!s}:e:null);function ee(e,t=null,s=null,r=0,n=null,o=e===he?0:1,l=!1,c=!1){const u={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Or(t),ref:t&&Ht(t),scopeId:lr,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:r,dynamicProps:n,dynamicChildren:null,appContext:null,ctx:ue};return c?(zs(u,s),o&128&&e.normalize(u)):s&&(u.shapeFlag|=V(s)?8:16),Et>0&&!l&&ve&&(u.patchFlag>0||o&6)&&u.patchFlag!==32&&ve.push(u),u}const L=ml;function ml(e,t=null,s=null,r=0,n=null,o=!1){if((!e||e===Vo)&&(e=Be),Cr(e)){const c=rt(e,t,!0);return s&&zs(c,s),Et>0&&!o&&ve&&(c.shapeFlag&6?ve[ve.indexOf(e)]=c:ve.push(c)),c.patchFlag|=-2,c}if(Pl(e)&&(e=e.__vccOpts),t){t=vl(t);let{class:c,style:u}=t;c&&!V(c)&&(t.class=it(c)),W(u)&&(Vn(u)&&!P(u)&&(u=G({},u)),t.style=Jt(u))}const l=V(e)?1:No(e)?128:gl(e)?64:W(e)?4:M(e)?2:0;return ee(e,t,s,r,n,l,o,!0)}function vl(e){return e?Vn(e)||ts in e?G({},e):e:null}function rt(e,t,s=!1){const{props:r,ref:n,patchFlag:o,children:l}=e,c=t?bl(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:c,key:c&&Or(c),ref:t&&t.ref?s&&n?P(n)?n.concat(Ht(t)):[n,Ht(t)]:Ht(t):n,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==he?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&rt(e.ssContent),ssFallback:e.ssFallback&&rt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function j(e=" ",t=0){return L(es,null,e,t)}function Z(e="",t=!1){return t?(R(),pe(Be,null,e)):L(Be,null,e)}function Oe(e){return e==null||typeof e=="boolean"?L(Be):P(e)?L(he,null,e.slice()):typeof e=="object"?Re(e):L(es,null,String(e))}function Re(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:rt(e)}function zs(e,t){let s=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(P(t))s=16;else if(typeof t=="object")if(r&65){const n=t.default;n&&(n._c&&(n._d=!1),zs(e,n()),n._c&&(n._d=!0));return}else{s=32;const n=t._;!n&&!(ts in t)?t._ctx=ue:n===3&&ue&&(ue.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else M(t)?(t={default:t,_ctx:ue},s=32):(t=String(t),r&64?(s=16,t=[j(t)]):s=8);e.children=t,e.shapeFlag|=s}function bl(...e){const t={};for(let s=0;soe=e),qs=e=>{Ve.length>1?Ve.forEach(t=>t(e)):Ve[0](e)};const ot=e=>{qs(e),e.scope.on()},Ye=()=>{oe&&oe.scope.off(),qs(null)};function Tr(e){return e.vnode.shapeFlag&4}let Ct=!1;function El(e,t=!1){Ct=t;const{props:s,children:r}=e.vnode,n=Tr(e);il(e,s,n,t),ul(e,r);const o=n?Cl(e,t):void 0;return Ct=!1,o}function Cl(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=Xn(new Proxy(e.ctx,Qo));const{setup:r}=s;if(r){const n=e.setupContext=r.length>1?Tl(e):null;ot(e),ct();const o=je(r,e,0,[e.props,n]);if(ft(),Ye(),Rn(o)){if(o.then(Ye,Ye),t)return o.then(l=>{wn(e,l,t)}).catch(l=>{Vt(l,e,0)});e.asyncDep=o}else wn(e,o,t)}else Pr(e,t)}function wn(e,t,s){M(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:W(t)&&(e.setupState=er(t)),Pr(e,s)}let En;function Pr(e,t,s){const r=e.type;if(!e.render){if(!t&&En&&!r.render){const n=r.template||ks(e).template;if(n){const{isCustomElement:o,compilerOptions:l}=e.appContext.config,{delimiters:c,compilerOptions:u}=r,a=G(G({isCustomElement:o,delimiters:c},l),u);r.render=En(n,a)}}e.render=r.render||be}ot(e),ct(),Go(e),ft(),Ye()}function Ol(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,s){return ae(e,"get","$attrs"),t[s]}}))}function Tl(e){const t=s=>{e.exposed=s||{}};return{get attrs(){return Ol(e)},slots:e.slots,emit:e.emit,expose:t}}function Ys(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(er(Xn(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in mt)return mt[s](e)},has(t,s){return s in t||s in mt}}))}function Pl(e){return M(e)&&"__vccOpts"in e}const Ts=(e,t)=>Co(e,t,Ct),Il=Symbol.for("v-scx"),Ml=()=>Dt(Il),Fl="3.3.4",Al="http://www.w3.org/2000/svg",ze=typeof document<"u"?document:null,Cn=ze&&ze.createElement("template"),$l={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,r)=>{const n=t?ze.createElementNS(Al,e):ze.createElement(e,s?{is:s}:void 0);return e==="select"&&r&&r.multiple!=null&&n.setAttribute("multiple",r.multiple),n},createText:e=>ze.createTextNode(e),createComment:e=>ze.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>ze.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,r,n,o){const l=s?s.previousSibling:t.lastChild;if(n&&(n===o||n.nextSibling))for(;t.insertBefore(n.cloneNode(!0),s),!(n===o||!(n=n.nextSibling)););else{Cn.innerHTML=r?`${e}`:e;const c=Cn.content;if(r){const u=c.firstChild;for(;u.firstChild;)c.appendChild(u.firstChild);c.removeChild(u)}t.insertBefore(c,s)}return[l?l.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}};function Rl(e,t,s){const r=e._vtc;r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}function Sl(e,t,s){const r=e.style,n=V(s);if(s&&!n){if(t&&!V(t))for(const o in t)s[o]==null&&Ps(r,o,"");for(const o in s)Ps(r,o,s[o])}else{const o=r.display;n?t!==s&&(r.cssText=s):t&&e.removeAttribute("style"),"_vod"in e&&(r.display=o)}}const On=/\s*!important$/;function Ps(e,t,s){if(P(s))s.forEach(r=>Ps(e,t,r));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const r=jl(e,t);On.test(s)?e.setProperty(lt(r),s.replace(On,""),"important"):e[r]=s}}const Tn=["Webkit","Moz","ms"],ds={};function jl(e,t){const s=ds[t];if(s)return s;let r=st(t);if(r!=="filter"&&r in e)return ds[t]=r;r=Nn(r);for(let n=0;nhs||(Kl.then(()=>hs=0),hs=Date.now());function Wl(e,t){const s=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=s.attached)return;ye(zl(r,s.value),t,5,[r])};return s.value=e,s.attached=kl(),s}function zl(e,t){if(P(t)){const s=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{s.call(e),e._stopped=!0},t.map(r=>n=>!n._stopped&&r&&r(n))}else return t}const Mn=/^on[a-z]/,ql=(e,t,s,r,n=!1,o,l,c,u)=>{t==="class"?Rl(e,r,n):t==="style"?Sl(e,s,r):zt(t)?Ms(t)||Ll(e,t,s,r,l):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Yl(e,t,r,n))?Bl(e,t,r,o,l,c,u):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Nl(e,t,r,n))};function Yl(e,t,s,r){return r?!!(t==="innerHTML"||t==="textContent"||t in e&&Mn.test(t)&&M(s)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||Mn.test(t)&&V(s)?!1:t in e}const Jl=G({patchProp:ql},$l);let Fn;function Zl(){return Fn||(Fn=dl(Jl))}const Vl=(...e)=>{const t=Zl().createApp(...e),{mount:s}=t;return t.mount=r=>{const n=Xl(r);if(!n)return;const o=t._component;!M(o)&&!o.render&&!o.template&&(o.template=n.innerHTML),n.innerHTML="";const l=s(n,!1,n instanceof SVGElement);return n instanceof Element&&(n.removeAttribute("v-cloak"),n.setAttribute("data-v-app","")),l},t};function Xl(e){return V(e)?document.querySelector(e):e}const Js=(e,t)=>{const s=e.__vccOpts||e;for(const[r,n]of t)s[r]=n;return s},Ql={},Gl={xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},ei=ee("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18"},null,-1),ti=[ei];function si(e,t){return R(),q("svg",Gl,ti)}const ni=Js(Ql,[["render",si]]),ri={},oi={xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},li=ee("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3"},null,-1),ii=[li];function ci(e,t){return R(),q("svg",oi,ii)}const fi=Js(ri,[["render",ci]]),ui={class:"inline-block text-sm bg-gray-200 rounded-full overflow-hidden relative"},ai=Qt({__name:"Progress",props:{value:{},max:{}},setup(e){return(t,s)=>(R(),q("div",ui,[ee("div",{class:it(["px-2 text-sm transition-[width] duration-500 whitespace-nowrap",{"bg-gray-400/50":t.value/t.max<.8,"bg-orange-300":t.value/t.max>=.8&&t.value/t.max<.9,"bg-red-300":t.value/t.max>=.9}]),style:Jt({width:`${t.value/t.max*100}%`})},[hr(t.$slots,"default")],6)]))}}),di={},hi={class:"inline-block bg-gray-200 px-2 rounded-full text-sm"};function pi(e,t){return R(),q("div",hi,[hr(e.$slots,"default")])}const gi=Js(di,[["render",pi]]),_i=Qt({__name:"StatusIndicator",props:{status:{type:Boolean}},setup(e){return(t,s)=>(R(),q("div",{class:it(["rounded-full inline-block",{"bg-green-400":t.status,"bg-red-500":!t.status}])},null,2))}});function Ce(e,t=2){if(e===0)return"0 B";const s=1024,r=t<0?0:t,n=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],o=Math.floor(Math.log(e)/Math.log(s));return`${Number.parseFloat((e/s**o).toFixed(r))} ${n[o]}`}function mi(e){const t=new Date(e*1e3),s=t.getFullYear(),r=(t.getMonth()+1).toString().padStart(2,"0"),n=t.getDate().toString().padStart(2,"0"),o=t.getHours().toString().padStart(2,"0"),l=t.getMinutes().toString().padStart(2,"0"),c=t.getSeconds().toString().padStart(2,"0");return`${s}/${r}/${n} ${o}:${l}:${c}`}function ps(e){return e.online4||e.online6}function vi(e){return/[\uD800-\uDBFF][\uDC00-\uDFFF]/g.test(e)}const bi={class:"rounded-xl px-4 py-3 transition-all relative bg-gray-100 border border-transparent hover:border-gray-400 hover:shadow-md hover:bg-white duration-300"},yi={class:"absolute right-4 top-4 group flex flex-col items-end"},xi={class:"hidden group-hover:block p-2 rounded-xl border text-sm bg-white z-[9999] mt-1 border-gray-400"},wi={class:"flex gap-2"},Ei={class:"flex items-center gap-1"},Ci={class:"flex items-center gap-1"},Oi={key:0},Ti=ee("br",null,null,-1),Pi={class:"text-lg flex items-center gap-2"},Ii={key:0},Mi=["src","alt"],Fi=["src","alt"],Ai={class:"flex items-center gap-2"},$i={key:0,class:"flex items-center gap-2"},Ri={key:1,class:"flex items-center gap-2"},Si={key:2,class:"flex items-center gap-2"},ji={key:3,class:"flex items-center gap-2"},Ni={key:4,class:"flex items-center gap-2"},Bi={key:5},Di={class:"flex gap-1 flex-wrap mt-1"},Hi=Qt({__name:"ServerItem",props:{server:{}},setup(e){const t=e,s=Ts(()=>{if(!t.server.labels)return{};const n=t.server.labels.split(";"),o={};return n.forEach(l=>{if(l==="")return;const[c,u]=l.split("=");o[c]=u}),o}),r=Ts(()=>!t.server.load&&!t.server.load_1&&!t.server.load_5&&!t.server.load_15);return(n,o)=>{const l=_i,c=gi,u=ai,a=fi,g=ni;return R(),q("div",bi,[ee("div",yi,[L(l,{status:U(ps)(n.server),class:"w-3 h-3"},null,8,["status"]),ee("div",xi,[ee("div",wi,[ee("div",Ei,[j(" IPv4 "),L(l,{status:n.server.online4,class:"w-2 h-2"},null,8,["status"])]),ee("div",Ci,[j(" IPv6 "),L(l,{status:n.server.online6,class:"w-2 h-2"},null,8,["status"])])]),n.server.latest_ts?(R(),q("div",Oi,[j(" 最后上报时间"),Ti,j(" "+k(U(mi)(n.server.latest_ts)),1)])):Z("",!0)])]),ee("div",Pi,[U(vi)(n.server.location)?(R(),q("span",Ii,k(n.server.location),1)):(R(),q("img",{key:1,src:`/image/flags/${n.server.location.toLowerCase()}.svg`,alt:`${n.server.location} flag`,class:"h-4 inline-block rounded-sm"},null,8,Mi)),U(s).os?(R(),q("img",{key:2,src:`/image/os/${U(s).os}.svg`,alt:`${U(s).os} os`,class:"h-4 inline-block rounded-sm"},null,8,Fi)):Z("",!0),j(" "+k(n.server.alias||n.server.name),1)]),ee("div",null,[j(" 运行时间 "),ee("span",{class:it({"text-red-500":!U(ps)(n.server)})},k(U(ps)(n.server)?n.server.uptime:"离线"),3)]),ee("div",Ai,[j(" 负载 "),U(r)?(R(),pe(c,{key:0},{default:Q(()=>[j(" 无数据 ")]),_:1})):Z("",!0),n.server.load?(R(),pe(c,{key:1},{default:Q(()=>[j(k(n.server.load),1)]),_:1})):Z("",!0),n.server.load_1?(R(),pe(c,{key:2},{default:Q(()=>[j(k(n.server.load_1),1)]),_:1})):Z("",!0),n.server.load_5?(R(),pe(c,{key:3},{default:Q(()=>[j(k(n.server.load_5),1)]),_:1})):Z("",!0),n.server.load_15?(R(),pe(c,{key:4},{default:Q(()=>[j(k(n.server.load_15),1)]),_:1})):Z("",!0)]),n.server.cpu?(R(),q("div",$i,[j(" CPU "),L(u,{value:n.server.cpu,max:100,text:`${n.server.cpu}%`,class:"flex-1"},{default:Q(()=>[j(k(n.server.cpu)+"% ",1)]),_:1},8,["value","text"])])):Z("",!0),n.server.memory_total?(R(),q("div",Ri,[j(" 内存 "),L(u,{value:n.server.memory_used,max:n.server.memory_total,class:"flex-1"},{default:Q(()=>[j(k(U(Ce)(n.server.memory_used*1024))+" / "+k(U(Ce)(n.server.memory_total*1024)),1)]),_:1},8,["value","max"])])):Z("",!0),n.server.hdd_total?(R(),q("div",Si,[j(" 硬盘 "),L(u,{value:n.server.hdd_used,max:n.server.hdd_total,class:"flex-1"},{default:Q(()=>[j(k(U(Ce)(n.server.hdd_used*1024*1024))+" / "+k(U(Ce)(n.server.hdd_total*1024*1024)),1)]),_:1},8,["value","max"])])):Z("",!0),n.server.network_rx?(R(),q("div",ji,[j(" 网络 "),L(c,{class:"flex items-center"},{default:Q(()=>[L(a,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_rx,1))+"/s ",1)]),_:1}),L(c,{class:"flex items-center"},{default:Q(()=>[L(g,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_tx,1))+"/s ",1)]),_:1})])):Z("",!0),n.server.network_in?(R(),q("div",Ni,[j(" 流量 "),L(c,{class:"flex items-center"},{default:Q(()=>[L(a,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_in,1)),1)]),_:1}),L(c,{class:"flex items-center"},{default:Q(()=>[L(g,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_out,1)),1)]),_:1})])):Z("",!0),n.server.swap_total?(R(),q("div",Bi,[j(" SWAP "),L(c,null,{default:Q(()=>[j(k(U(Ce)(n.server.swap_used*1024))+" / "+k(U(Ce)(n.server.swap_total*1024)),1)]),_:1})])):Z("",!0),ee("div",Di,[n.server.tcp_count?(R(),pe(c,{key:0},{default:Q(()=>[j(" TCP "+k(n.server.tcp_count),1)]),_:1})):Z("",!0),n.server.udp_count?(R(),pe(c,{key:1},{default:Q(()=>[j(" UDP "+k(n.server.udp_count),1)]),_:1})):Z("",!0),n.server.process_count?(R(),pe(c,{key:2},{default:Q(()=>[j(" 进程 "+k(n.server.process_count),1)]),_:1})):Z("",!0),n.server.thread_count?(R(),pe(c,{key:3},{default:Q(()=>[j(" 线程 "+k(n.server.thread_count),1)]),_:1})):Z("",!0)])])}}}),Li={key:0,class:"w-fit mx-auto my-2"},Ui={key:1,class:"w-fit mx-auto my-2"},Ki={key:2,class:"flex flex-wrap gap-x-4 gap-y-3"},ki=ee("div",{class:"h-16"},null,-1),An="/json/stats.json",Wi=Qt({__name:"App",setup(e){const t=jt(),s=jt(!0),r=jt(!1),n=jt(!1);ar(()=>{fetch(An).then(l=>l.json()).then(l=>{t.value=l,setInterval(()=>{o()},500)}).catch(()=>{r.value=!0}).finally(()=>{s.value=!1})});function o(){n.value||(n.value=!0,fetch(An).then(l=>l.json()).then(l=>{t.value=l,r.value=!1}).catch(()=>{r.value=!0}).finally(()=>{n.value=!1}))}return(l,c)=>{const u=Hi;return R(),q(he,null,[U(s)?(R(),q("div",Li," 加载中 ")):Z("",!0),U(r)?(R(),q("div",Ui," 数据加载失败,请尝试刷新页面或检查 ServerStatus 服务端状态 ")):Z("",!0),U(t)?(R(),q("div",Ki,[(R(!0),q(he,null,Xo(U(t).servers,(a,g)=>(R(),pe(u,{key:g,server:a,class:"flex-1 min-w-[300px]"},null,8,["server"]))),128))])):Z("",!0),ki],64)}}});const zi=Vl(Wi);zi.mount("#app"); diff --git a/web/image/flags/ac.svg b/web/image/flags/ac.svg new file mode 100644 index 00000000..1a6d5080 --- /dev/null +++ b/web/image/flags/ac.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ad.svg b/web/image/flags/ad.svg new file mode 100644 index 00000000..726f981b --- /dev/null +++ b/web/image/flags/ad.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ae.svg b/web/image/flags/ae.svg new file mode 100644 index 00000000..b7acdbdb --- /dev/null +++ b/web/image/flags/ae.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/af.svg b/web/image/flags/af.svg new file mode 100644 index 00000000..6e755396 --- /dev/null +++ b/web/image/flags/af.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ag.svg b/web/image/flags/ag.svg new file mode 100644 index 00000000..3bce7482 --- /dev/null +++ b/web/image/flags/ag.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/ai.svg b/web/image/flags/ai.svg new file mode 100644 index 00000000..cf91b39b --- /dev/null +++ b/web/image/flags/ai.svg @@ -0,0 +1,758 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/al.svg b/web/image/flags/al.svg new file mode 100644 index 00000000..4e7098f3 --- /dev/null +++ b/web/image/flags/al.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/am.svg b/web/image/flags/am.svg new file mode 100644 index 00000000..99fa4dc5 --- /dev/null +++ b/web/image/flags/am.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/ao.svg b/web/image/flags/ao.svg new file mode 100644 index 00000000..4dc39f6a --- /dev/null +++ b/web/image/flags/ao.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/aq.svg b/web/image/flags/aq.svg new file mode 100644 index 00000000..53840ccc --- /dev/null +++ b/web/image/flags/aq.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/ar.svg b/web/image/flags/ar.svg new file mode 100644 index 00000000..d1810f25 --- /dev/null +++ b/web/image/flags/ar.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/as.svg b/web/image/flags/as.svg new file mode 100644 index 00000000..88e2ca5d --- /dev/null +++ b/web/image/flags/as.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/at.svg b/web/image/flags/at.svg new file mode 100644 index 00000000..c2825088 --- /dev/null +++ b/web/image/flags/at.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/au.svg b/web/image/flags/au.svg new file mode 100644 index 00000000..407fef43 --- /dev/null +++ b/web/image/flags/au.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/aw.svg b/web/image/flags/aw.svg new file mode 100644 index 00000000..e840233b --- /dev/null +++ b/web/image/flags/aw.svg @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ax.svg b/web/image/flags/ax.svg new file mode 100644 index 00000000..9f04648b --- /dev/null +++ b/web/image/flags/ax.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/az.svg b/web/image/flags/az.svg new file mode 100644 index 00000000..8e56ef53 --- /dev/null +++ b/web/image/flags/az.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/ba.svg b/web/image/flags/ba.svg new file mode 100644 index 00000000..7c304215 --- /dev/null +++ b/web/image/flags/ba.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/image/flags/bb.svg b/web/image/flags/bb.svg new file mode 100644 index 00000000..420a6885 --- /dev/null +++ b/web/image/flags/bb.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/bd.svg b/web/image/flags/bd.svg new file mode 100644 index 00000000..16b794de --- /dev/null +++ b/web/image/flags/bd.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/be.svg b/web/image/flags/be.svg new file mode 100644 index 00000000..327f28fa --- /dev/null +++ b/web/image/flags/be.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/bf.svg b/web/image/flags/bf.svg new file mode 100644 index 00000000..47138225 --- /dev/null +++ b/web/image/flags/bf.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/bg.svg b/web/image/flags/bg.svg new file mode 100644 index 00000000..b100dd0d --- /dev/null +++ b/web/image/flags/bg.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/bh.svg b/web/image/flags/bh.svg new file mode 100644 index 00000000..7a2ea549 --- /dev/null +++ b/web/image/flags/bh.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/bi.svg b/web/image/flags/bi.svg new file mode 100644 index 00000000..a37bc67f --- /dev/null +++ b/web/image/flags/bi.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/bj.svg b/web/image/flags/bj.svg new file mode 100644 index 00000000..871c57ee --- /dev/null +++ b/web/image/flags/bj.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/bl.svg b/web/image/flags/bl.svg new file mode 100644 index 00000000..15803ff9 --- /dev/null +++ b/web/image/flags/bl.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/bm.svg b/web/image/flags/bm.svg new file mode 100644 index 00000000..330d5ec3 --- /dev/null +++ b/web/image/flags/bm.svg @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/bn.svg b/web/image/flags/bn.svg new file mode 100644 index 00000000..19f15fa5 --- /dev/null +++ b/web/image/flags/bn.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/bo.svg b/web/image/flags/bo.svg new file mode 100644 index 00000000..391e2267 --- /dev/null +++ b/web/image/flags/bo.svg @@ -0,0 +1,676 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/bq.svg b/web/image/flags/bq.svg new file mode 100644 index 00000000..0e6bc76e --- /dev/null +++ b/web/image/flags/bq.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/br.svg b/web/image/flags/br.svg new file mode 100644 index 00000000..354a7013 --- /dev/null +++ b/web/image/flags/br.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/bs.svg b/web/image/flags/bs.svg new file mode 100644 index 00000000..b26d4769 --- /dev/null +++ b/web/image/flags/bs.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/bt.svg b/web/image/flags/bt.svg new file mode 100644 index 00000000..cea6006c --- /dev/null +++ b/web/image/flags/bt.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/bv.svg b/web/image/flags/bv.svg new file mode 100644 index 00000000..86431fcc --- /dev/null +++ b/web/image/flags/bv.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/bw.svg b/web/image/flags/bw.svg new file mode 100644 index 00000000..a1c8db0a --- /dev/null +++ b/web/image/flags/bw.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/by.svg b/web/image/flags/by.svg new file mode 100644 index 00000000..20ae52bd --- /dev/null +++ b/web/image/flags/by.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/bz.svg b/web/image/flags/bz.svg new file mode 100644 index 00000000..fbc6d7cb --- /dev/null +++ b/web/image/flags/bz.svg @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ca.svg b/web/image/flags/ca.svg new file mode 100644 index 00000000..f1b2c968 --- /dev/null +++ b/web/image/flags/ca.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/cc.svg b/web/image/flags/cc.svg new file mode 100644 index 00000000..c4457dee --- /dev/null +++ b/web/image/flags/cc.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/cd.svg b/web/image/flags/cd.svg new file mode 100644 index 00000000..e106ddd5 --- /dev/null +++ b/web/image/flags/cd.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/cefta.svg b/web/image/flags/cefta.svg new file mode 100644 index 00000000..d66e18be --- /dev/null +++ b/web/image/flags/cefta.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/cf.svg b/web/image/flags/cf.svg new file mode 100644 index 00000000..fd30063c --- /dev/null +++ b/web/image/flags/cf.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/cg.svg b/web/image/flags/cg.svg new file mode 100644 index 00000000..a2902345 --- /dev/null +++ b/web/image/flags/cg.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/image/flags/ch.svg b/web/image/flags/ch.svg new file mode 100644 index 00000000..b42d6709 --- /dev/null +++ b/web/image/flags/ch.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/ci.svg b/web/image/flags/ci.svg new file mode 100644 index 00000000..e400f0c1 --- /dev/null +++ b/web/image/flags/ci.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/ck.svg b/web/image/flags/ck.svg new file mode 100644 index 00000000..18e547b1 --- /dev/null +++ b/web/image/flags/ck.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/cl.svg b/web/image/flags/cl.svg new file mode 100644 index 00000000..50218c82 --- /dev/null +++ b/web/image/flags/cl.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/cm.svg b/web/image/flags/cm.svg new file mode 100644 index 00000000..d06f6560 --- /dev/null +++ b/web/image/flags/cm.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/cn.svg b/web/image/flags/cn.svg new file mode 100644 index 00000000..24162360 --- /dev/null +++ b/web/image/flags/cn.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/image/flags/co.svg b/web/image/flags/co.svg new file mode 100644 index 00000000..ebd0a0fb --- /dev/null +++ b/web/image/flags/co.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/cp.svg b/web/image/flags/cp.svg new file mode 100644 index 00000000..b3efb074 --- /dev/null +++ b/web/image/flags/cp.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/cr.svg b/web/image/flags/cr.svg new file mode 100644 index 00000000..5a409eeb --- /dev/null +++ b/web/image/flags/cr.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/cu.svg b/web/image/flags/cu.svg new file mode 100644 index 00000000..31cf99c2 --- /dev/null +++ b/web/image/flags/cu.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/cv.svg b/web/image/flags/cv.svg new file mode 100644 index 00000000..381985a7 --- /dev/null +++ b/web/image/flags/cv.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/cw.svg b/web/image/flags/cw.svg new file mode 100644 index 00000000..4294b5bc --- /dev/null +++ b/web/image/flags/cw.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/cx.svg b/web/image/flags/cx.svg new file mode 100644 index 00000000..39fa9b07 --- /dev/null +++ b/web/image/flags/cx.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/cy.svg b/web/image/flags/cy.svg new file mode 100644 index 00000000..b72473ab --- /dev/null +++ b/web/image/flags/cy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/cz.svg b/web/image/flags/cz.svg new file mode 100644 index 00000000..7913de38 --- /dev/null +++ b/web/image/flags/cz.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/de.svg b/web/image/flags/de.svg new file mode 100644 index 00000000..b08334b6 --- /dev/null +++ b/web/image/flags/de.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/dg.svg b/web/image/flags/dg.svg new file mode 100644 index 00000000..8ba67509 --- /dev/null +++ b/web/image/flags/dg.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/dj.svg b/web/image/flags/dj.svg new file mode 100644 index 00000000..674d7ef4 --- /dev/null +++ b/web/image/flags/dj.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/dk.svg b/web/image/flags/dk.svg new file mode 100644 index 00000000..563277f8 --- /dev/null +++ b/web/image/flags/dk.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/dm.svg b/web/image/flags/dm.svg new file mode 100644 index 00000000..7fa4dd8a --- /dev/null +++ b/web/image/flags/dm.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/do.svg b/web/image/flags/do.svg new file mode 100644 index 00000000..e8114b32 --- /dev/null +++ b/web/image/flags/do.svg @@ -0,0 +1,6745 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/dz.svg b/web/image/flags/dz.svg new file mode 100644 index 00000000..5ff29a74 --- /dev/null +++ b/web/image/flags/dz.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/ea.svg b/web/image/flags/ea.svg new file mode 100644 index 00000000..d55c9b6c --- /dev/null +++ b/web/image/flags/ea.svg @@ -0,0 +1,544 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ec.svg b/web/image/flags/ec.svg new file mode 100644 index 00000000..65b78858 --- /dev/null +++ b/web/image/flags/ec.svg @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ee.svg b/web/image/flags/ee.svg new file mode 100644 index 00000000..36ea288c --- /dev/null +++ b/web/image/flags/ee.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/eg.svg b/web/image/flags/eg.svg new file mode 100644 index 00000000..728538ba --- /dev/null +++ b/web/image/flags/eg.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/eh.svg b/web/image/flags/eh.svg new file mode 100644 index 00000000..87433715 --- /dev/null +++ b/web/image/flags/eh.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/image/flags/er.svg b/web/image/flags/er.svg new file mode 100644 index 00000000..2705295f --- /dev/null +++ b/web/image/flags/er.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/es-ct.svg b/web/image/flags/es-ct.svg new file mode 100644 index 00000000..4d859114 --- /dev/null +++ b/web/image/flags/es-ct.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/es-ga.svg b/web/image/flags/es-ga.svg new file mode 100644 index 00000000..cc52c846 --- /dev/null +++ b/web/image/flags/es-ga.svg @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/es.svg b/web/image/flags/es.svg new file mode 100644 index 00000000..815e0f84 --- /dev/null +++ b/web/image/flags/es.svg @@ -0,0 +1,544 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/et.svg b/web/image/flags/et.svg new file mode 100644 index 00000000..7075040b --- /dev/null +++ b/web/image/flags/et.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/eu.svg b/web/image/flags/eu.svg new file mode 100644 index 00000000..1bb04ecb --- /dev/null +++ b/web/image/flags/eu.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/fi.svg b/web/image/flags/fi.svg new file mode 100644 index 00000000..470be2d0 --- /dev/null +++ b/web/image/flags/fi.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/fj.svg b/web/image/flags/fj.svg new file mode 100644 index 00000000..2d7cd980 --- /dev/null +++ b/web/image/flags/fj.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/fk.svg b/web/image/flags/fk.svg new file mode 100644 index 00000000..8aeee57c --- /dev/null +++ b/web/image/flags/fk.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/fm.svg b/web/image/flags/fm.svg new file mode 100644 index 00000000..baa96683 --- /dev/null +++ b/web/image/flags/fm.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/image/flags/fo.svg b/web/image/flags/fo.svg new file mode 100644 index 00000000..898f6695 --- /dev/null +++ b/web/image/flags/fo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/image/flags/fr.svg b/web/image/flags/fr.svg new file mode 100644 index 00000000..1be61911 --- /dev/null +++ b/web/image/flags/fr.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/ga.svg b/web/image/flags/ga.svg new file mode 100644 index 00000000..76edab42 --- /dev/null +++ b/web/image/flags/ga.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/gb-eng.svg b/web/image/flags/gb-eng.svg new file mode 100644 index 00000000..12e3b67d --- /dev/null +++ b/web/image/flags/gb-eng.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/gb-nir.svg b/web/image/flags/gb-nir.svg new file mode 100644 index 00000000..e34b224b --- /dev/null +++ b/web/image/flags/gb-nir.svg @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/gb-sct.svg b/web/image/flags/gb-sct.svg new file mode 100644 index 00000000..f50cd322 --- /dev/null +++ b/web/image/flags/gb-sct.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/gb-wls.svg b/web/image/flags/gb-wls.svg new file mode 100644 index 00000000..6e15fd01 --- /dev/null +++ b/web/image/flags/gb-wls.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/gb.svg b/web/image/flags/gb.svg new file mode 100644 index 00000000..dbac25ea --- /dev/null +++ b/web/image/flags/gb.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/gd.svg b/web/image/flags/gd.svg new file mode 100644 index 00000000..dad1107f --- /dev/null +++ b/web/image/flags/gd.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ge.svg b/web/image/flags/ge.svg new file mode 100644 index 00000000..453898b0 --- /dev/null +++ b/web/image/flags/ge.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/gf.svg b/web/image/flags/gf.svg new file mode 100644 index 00000000..f8752d9e --- /dev/null +++ b/web/image/flags/gf.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/gg.svg b/web/image/flags/gg.svg new file mode 100644 index 00000000..e40a8387 --- /dev/null +++ b/web/image/flags/gg.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/gh.svg b/web/image/flags/gh.svg new file mode 100644 index 00000000..a6497de8 --- /dev/null +++ b/web/image/flags/gh.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/gi.svg b/web/image/flags/gi.svg new file mode 100644 index 00000000..64a69e8b --- /dev/null +++ b/web/image/flags/gi.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/gl.svg b/web/image/flags/gl.svg new file mode 100644 index 00000000..eb5a52e9 --- /dev/null +++ b/web/image/flags/gl.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/gm.svg b/web/image/flags/gm.svg new file mode 100644 index 00000000..2fbcb196 --- /dev/null +++ b/web/image/flags/gm.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/gn.svg b/web/image/flags/gn.svg new file mode 100644 index 00000000..40d6ad4f --- /dev/null +++ b/web/image/flags/gn.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/gp.svg b/web/image/flags/gp.svg new file mode 100644 index 00000000..1b381588 --- /dev/null +++ b/web/image/flags/gp.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/gq.svg b/web/image/flags/gq.svg new file mode 100644 index 00000000..ba2acf28 --- /dev/null +++ b/web/image/flags/gq.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/gr.svg b/web/image/flags/gr.svg new file mode 100644 index 00000000..599741ee --- /dev/null +++ b/web/image/flags/gr.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/image/flags/gs.svg b/web/image/flags/gs.svg new file mode 100644 index 00000000..7e0692c1 --- /dev/null +++ b/web/image/flags/gs.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/gt.svg b/web/image/flags/gt.svg new file mode 100644 index 00000000..be453241 --- /dev/null +++ b/web/image/flags/gt.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/gu.svg b/web/image/flags/gu.svg new file mode 100644 index 00000000..a5584ffd --- /dev/null +++ b/web/image/flags/gu.svg @@ -0,0 +1,23 @@ + + + + + + + + + + G + U + A + M + + + + + + + + + + diff --git a/web/image/flags/gw.svg b/web/image/flags/gw.svg new file mode 100644 index 00000000..9e0aeebd --- /dev/null +++ b/web/image/flags/gw.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/gy.svg b/web/image/flags/gy.svg new file mode 100644 index 00000000..f4d9b8ab --- /dev/null +++ b/web/image/flags/gy.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/hk.svg b/web/image/flags/hk.svg new file mode 100644 index 00000000..e32924f1 --- /dev/null +++ b/web/image/flags/hk.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/hm.svg b/web/image/flags/hm.svg new file mode 100644 index 00000000..c0748d3b --- /dev/null +++ b/web/image/flags/hm.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/hn.svg b/web/image/flags/hn.svg new file mode 100644 index 00000000..6f929500 --- /dev/null +++ b/web/image/flags/hn.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/hr.svg b/web/image/flags/hr.svg new file mode 100644 index 00000000..70115ae9 --- /dev/null +++ b/web/image/flags/hr.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ht.svg b/web/image/flags/ht.svg new file mode 100644 index 00000000..9cddb293 --- /dev/null +++ b/web/image/flags/ht.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/hu.svg b/web/image/flags/hu.svg new file mode 100644 index 00000000..baddf7f5 --- /dev/null +++ b/web/image/flags/hu.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/ic.svg b/web/image/flags/ic.svg new file mode 100644 index 00000000..81e6ee2e --- /dev/null +++ b/web/image/flags/ic.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/id.svg b/web/image/flags/id.svg new file mode 100644 index 00000000..3b7c8fcf --- /dev/null +++ b/web/image/flags/id.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/ie.svg b/web/image/flags/ie.svg new file mode 100644 index 00000000..049be14d --- /dev/null +++ b/web/image/flags/ie.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/il.svg b/web/image/flags/il.svg new file mode 100644 index 00000000..d9d82135 --- /dev/null +++ b/web/image/flags/il.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/im.svg b/web/image/flags/im.svg new file mode 100644 index 00000000..ce1243c0 --- /dev/null +++ b/web/image/flags/im.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/in.svg b/web/image/flags/in.svg new file mode 100644 index 00000000..53c29b3a --- /dev/null +++ b/web/image/flags/in.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/io.svg b/web/image/flags/io.svg new file mode 100644 index 00000000..c0ed2af3 --- /dev/null +++ b/web/image/flags/io.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/iq.svg b/web/image/flags/iq.svg new file mode 100644 index 00000000..68917853 --- /dev/null +++ b/web/image/flags/iq.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/image/flags/ir.svg b/web/image/flags/ir.svg new file mode 100644 index 00000000..c937a369 --- /dev/null +++ b/web/image/flags/ir.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/is.svg b/web/image/flags/is.svg new file mode 100644 index 00000000..b0828a4c --- /dev/null +++ b/web/image/flags/is.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/image/flags/it.svg b/web/image/flags/it.svg new file mode 100644 index 00000000..20a8bfdc --- /dev/null +++ b/web/image/flags/it.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/je.svg b/web/image/flags/je.svg new file mode 100644 index 00000000..b65965cc --- /dev/null +++ b/web/image/flags/je.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/jm.svg b/web/image/flags/jm.svg new file mode 100644 index 00000000..e03a3422 --- /dev/null +++ b/web/image/flags/jm.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/jo.svg b/web/image/flags/jo.svg new file mode 100644 index 00000000..df0ce75f --- /dev/null +++ b/web/image/flags/jo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/image/flags/jp.svg b/web/image/flags/jp.svg new file mode 100644 index 00000000..90af6c49 --- /dev/null +++ b/web/image/flags/jp.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/image/flags/ke.svg b/web/image/flags/ke.svg new file mode 100644 index 00000000..ad190f53 --- /dev/null +++ b/web/image/flags/ke.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/kg.svg b/web/image/flags/kg.svg new file mode 100644 index 00000000..1d237fe3 --- /dev/null +++ b/web/image/flags/kg.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/kh.svg b/web/image/flags/kh.svg new file mode 100644 index 00000000..984e84e5 --- /dev/null +++ b/web/image/flags/kh.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ki.svg b/web/image/flags/ki.svg new file mode 100644 index 00000000..c4693700 --- /dev/null +++ b/web/image/flags/ki.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/km.svg b/web/image/flags/km.svg new file mode 100644 index 00000000..fda3a53f --- /dev/null +++ b/web/image/flags/km.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/image/flags/kn.svg b/web/image/flags/kn.svg new file mode 100644 index 00000000..f96b06cd --- /dev/null +++ b/web/image/flags/kn.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/kp.svg b/web/image/flags/kp.svg new file mode 100644 index 00000000..b405e454 --- /dev/null +++ b/web/image/flags/kp.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/kr.svg b/web/image/flags/kr.svg new file mode 100644 index 00000000..39fa999e --- /dev/null +++ b/web/image/flags/kr.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/kw.svg b/web/image/flags/kw.svg new file mode 100644 index 00000000..d55aa19f --- /dev/null +++ b/web/image/flags/kw.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/ky.svg b/web/image/flags/ky.svg new file mode 100644 index 00000000..103af5ba --- /dev/null +++ b/web/image/flags/ky.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/kz.svg b/web/image/flags/kz.svg new file mode 100644 index 00000000..64776c38 --- /dev/null +++ b/web/image/flags/kz.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/la.svg b/web/image/flags/la.svg new file mode 100644 index 00000000..cd7ea9da --- /dev/null +++ b/web/image/flags/la.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/image/flags/lb.svg b/web/image/flags/lb.svg new file mode 100644 index 00000000..f8b8b6d1 --- /dev/null +++ b/web/image/flags/lb.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/lc.svg b/web/image/flags/lc.svg new file mode 100644 index 00000000..46bbc6cc --- /dev/null +++ b/web/image/flags/lc.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/li.svg b/web/image/flags/li.svg new file mode 100644 index 00000000..d557d314 --- /dev/null +++ b/web/image/flags/li.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/lk.svg b/web/image/flags/lk.svg new file mode 100644 index 00000000..416c0f07 --- /dev/null +++ b/web/image/flags/lk.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/lr.svg b/web/image/flags/lr.svg new file mode 100644 index 00000000..00252212 --- /dev/null +++ b/web/image/flags/lr.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/ls.svg b/web/image/flags/ls.svg new file mode 100644 index 00000000..e7016502 --- /dev/null +++ b/web/image/flags/ls.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/lt.svg b/web/image/flags/lt.svg new file mode 100644 index 00000000..90ec5d24 --- /dev/null +++ b/web/image/flags/lt.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/lu.svg b/web/image/flags/lu.svg new file mode 100644 index 00000000..c31d2bfa --- /dev/null +++ b/web/image/flags/lu.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/lv.svg b/web/image/flags/lv.svg new file mode 100644 index 00000000..6a9e75ec --- /dev/null +++ b/web/image/flags/lv.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/ly.svg b/web/image/flags/ly.svg new file mode 100644 index 00000000..7324a87d --- /dev/null +++ b/web/image/flags/ly.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/ma.svg b/web/image/flags/ma.svg new file mode 100644 index 00000000..7ce56eff --- /dev/null +++ b/web/image/flags/ma.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/mc.svg b/web/image/flags/mc.svg new file mode 100644 index 00000000..9cb6c9e8 --- /dev/null +++ b/web/image/flags/mc.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/md.svg b/web/image/flags/md.svg new file mode 100644 index 00000000..a806572c --- /dev/null +++ b/web/image/flags/md.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/me.svg b/web/image/flags/me.svg new file mode 100644 index 00000000..b56cce09 --- /dev/null +++ b/web/image/flags/me.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/mf.svg b/web/image/flags/mf.svg new file mode 100644 index 00000000..0e5ae112 --- /dev/null +++ b/web/image/flags/mf.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/mg.svg b/web/image/flags/mg.svg new file mode 100644 index 00000000..5fa2d244 --- /dev/null +++ b/web/image/flags/mg.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/mh.svg b/web/image/flags/mh.svg new file mode 100644 index 00000000..46351e54 --- /dev/null +++ b/web/image/flags/mh.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/mk.svg b/web/image/flags/mk.svg new file mode 100644 index 00000000..4f5cae77 --- /dev/null +++ b/web/image/flags/mk.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/ml.svg b/web/image/flags/ml.svg new file mode 100644 index 00000000..6f6b7169 --- /dev/null +++ b/web/image/flags/ml.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/mm.svg b/web/image/flags/mm.svg new file mode 100644 index 00000000..35277829 --- /dev/null +++ b/web/image/flags/mm.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/image/flags/mn.svg b/web/image/flags/mn.svg new file mode 100644 index 00000000..56cb0729 --- /dev/null +++ b/web/image/flags/mn.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/mo.svg b/web/image/flags/mo.svg new file mode 100644 index 00000000..6b70cc72 --- /dev/null +++ b/web/image/flags/mo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/mp.svg b/web/image/flags/mp.svg new file mode 100644 index 00000000..d94f688b --- /dev/null +++ b/web/image/flags/mp.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/mq.svg b/web/image/flags/mq.svg new file mode 100644 index 00000000..750b396e --- /dev/null +++ b/web/image/flags/mq.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/mr.svg b/web/image/flags/mr.svg new file mode 100644 index 00000000..e9cc2916 --- /dev/null +++ b/web/image/flags/mr.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/ms.svg b/web/image/flags/ms.svg new file mode 100644 index 00000000..a1e52d9d --- /dev/null +++ b/web/image/flags/ms.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/mt.svg b/web/image/flags/mt.svg new file mode 100644 index 00000000..676e801c --- /dev/null +++ b/web/image/flags/mt.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/mu.svg b/web/image/flags/mu.svg new file mode 100644 index 00000000..82d7a3be --- /dev/null +++ b/web/image/flags/mu.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/mv.svg b/web/image/flags/mv.svg new file mode 100644 index 00000000..10450f98 --- /dev/null +++ b/web/image/flags/mv.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/mw.svg b/web/image/flags/mw.svg new file mode 100644 index 00000000..113aae54 --- /dev/null +++ b/web/image/flags/mw.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/image/flags/mx.svg b/web/image/flags/mx.svg new file mode 100644 index 00000000..42191950 --- /dev/null +++ b/web/image/flags/mx.svg @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/my.svg b/web/image/flags/my.svg new file mode 100644 index 00000000..773a4327 --- /dev/null +++ b/web/image/flags/my.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/mz.svg b/web/image/flags/mz.svg new file mode 100644 index 00000000..dab81a6e --- /dev/null +++ b/web/image/flags/mz.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/na.svg b/web/image/flags/na.svg new file mode 100644 index 00000000..3b9202b7 --- /dev/null +++ b/web/image/flags/na.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/image/flags/nc.svg b/web/image/flags/nc.svg new file mode 100644 index 00000000..96795408 --- /dev/null +++ b/web/image/flags/nc.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/ne.svg b/web/image/flags/ne.svg new file mode 100644 index 00000000..39a82b82 --- /dev/null +++ b/web/image/flags/ne.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/nf.svg b/web/image/flags/nf.svg new file mode 100644 index 00000000..ecdb4a3b --- /dev/null +++ b/web/image/flags/nf.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/ng.svg b/web/image/flags/ng.svg new file mode 100644 index 00000000..81eb35f7 --- /dev/null +++ b/web/image/flags/ng.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/ni.svg b/web/image/flags/ni.svg new file mode 100644 index 00000000..64d2aa0e --- /dev/null +++ b/web/image/flags/ni.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/nl.svg b/web/image/flags/nl.svg new file mode 100644 index 00000000..4faaf498 --- /dev/null +++ b/web/image/flags/nl.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/no.svg b/web/image/flags/no.svg new file mode 100644 index 00000000..a5f2a152 --- /dev/null +++ b/web/image/flags/no.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/np.svg b/web/image/flags/np.svg new file mode 100644 index 00000000..2f5e1f3c --- /dev/null +++ b/web/image/flags/np.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/nr.svg b/web/image/flags/nr.svg new file mode 100644 index 00000000..c7db7dd2 --- /dev/null +++ b/web/image/flags/nr.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/image/flags/nu.svg b/web/image/flags/nu.svg new file mode 100644 index 00000000..4067baff --- /dev/null +++ b/web/image/flags/nu.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/image/flags/nz.svg b/web/image/flags/nz.svg new file mode 100644 index 00000000..8ae592a4 --- /dev/null +++ b/web/image/flags/nz.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/om.svg b/web/image/flags/om.svg new file mode 100644 index 00000000..5be12ed1 --- /dev/null +++ b/web/image/flags/om.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/pa.svg b/web/image/flags/pa.svg new file mode 100644 index 00000000..658c87e1 --- /dev/null +++ b/web/image/flags/pa.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/pe.svg b/web/image/flags/pe.svg new file mode 100644 index 00000000..eeb29a32 --- /dev/null +++ b/web/image/flags/pe.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/pf.svg b/web/image/flags/pf.svg new file mode 100644 index 00000000..1b35cdb2 --- /dev/null +++ b/web/image/flags/pf.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/pg.svg b/web/image/flags/pg.svg new file mode 100644 index 00000000..1080add5 --- /dev/null +++ b/web/image/flags/pg.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/ph.svg b/web/image/flags/ph.svg new file mode 100644 index 00000000..65489e1c --- /dev/null +++ b/web/image/flags/ph.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/pk.svg b/web/image/flags/pk.svg new file mode 100644 index 00000000..0babde69 --- /dev/null +++ b/web/image/flags/pk.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/pl.svg b/web/image/flags/pl.svg new file mode 100644 index 00000000..0fa51452 --- /dev/null +++ b/web/image/flags/pl.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/pm.svg b/web/image/flags/pm.svg new file mode 100644 index 00000000..42bfcee0 --- /dev/null +++ b/web/image/flags/pm.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/pn.svg b/web/image/flags/pn.svg new file mode 100644 index 00000000..972792f8 --- /dev/null +++ b/web/image/flags/pn.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/pr.svg b/web/image/flags/pr.svg new file mode 100644 index 00000000..964b421f --- /dev/null +++ b/web/image/flags/pr.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/ps.svg b/web/image/flags/ps.svg new file mode 100644 index 00000000..ddd1dc1b --- /dev/null +++ b/web/image/flags/ps.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/pt.svg b/web/image/flags/pt.svg new file mode 100644 index 00000000..afd2e4a3 --- /dev/null +++ b/web/image/flags/pt.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/pw.svg b/web/image/flags/pw.svg new file mode 100644 index 00000000..77547c7f --- /dev/null +++ b/web/image/flags/pw.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/image/flags/py.svg b/web/image/flags/py.svg new file mode 100644 index 00000000..bfbf01f1 --- /dev/null +++ b/web/image/flags/py.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/qa.svg b/web/image/flags/qa.svg new file mode 100644 index 00000000..bd493c38 --- /dev/null +++ b/web/image/flags/qa.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/re.svg b/web/image/flags/re.svg new file mode 100644 index 00000000..6c56aa41 --- /dev/null +++ b/web/image/flags/re.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/ro.svg b/web/image/flags/ro.svg new file mode 100644 index 00000000..fda0f7be --- /dev/null +++ b/web/image/flags/ro.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/rs.svg b/web/image/flags/rs.svg new file mode 100644 index 00000000..86ad291a --- /dev/null +++ b/web/image/flags/rs.svg @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ru.svg b/web/image/flags/ru.svg new file mode 100644 index 00000000..f4d27efc --- /dev/null +++ b/web/image/flags/ru.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/rw.svg b/web/image/flags/rw.svg new file mode 100644 index 00000000..2c6c5d90 --- /dev/null +++ b/web/image/flags/rw.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/sa.svg b/web/image/flags/sa.svg new file mode 100644 index 00000000..6fcf86b0 --- /dev/null +++ b/web/image/flags/sa.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/sb.svg b/web/image/flags/sb.svg new file mode 100644 index 00000000..f450a9c6 --- /dev/null +++ b/web/image/flags/sb.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/sc.svg b/web/image/flags/sc.svg new file mode 100644 index 00000000..9a46b369 --- /dev/null +++ b/web/image/flags/sc.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/sd.svg b/web/image/flags/sd.svg new file mode 100644 index 00000000..c00a1a53 --- /dev/null +++ b/web/image/flags/sd.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/se.svg b/web/image/flags/se.svg new file mode 100644 index 00000000..0e41780e --- /dev/null +++ b/web/image/flags/se.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/sg.svg b/web/image/flags/sg.svg new file mode 100644 index 00000000..c0d3d083 --- /dev/null +++ b/web/image/flags/sg.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/sh.svg b/web/image/flags/sh.svg new file mode 100644 index 00000000..131b069a --- /dev/null +++ b/web/image/flags/sh.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/si.svg b/web/image/flags/si.svg new file mode 100644 index 00000000..223fc495 --- /dev/null +++ b/web/image/flags/si.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/sj.svg b/web/image/flags/sj.svg new file mode 100644 index 00000000..bb2799ce --- /dev/null +++ b/web/image/flags/sj.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/sk.svg b/web/image/flags/sk.svg new file mode 100644 index 00000000..a1953fa6 --- /dev/null +++ b/web/image/flags/sk.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/sl.svg b/web/image/flags/sl.svg new file mode 100644 index 00000000..a07baf75 --- /dev/null +++ b/web/image/flags/sl.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/sm.svg b/web/image/flags/sm.svg new file mode 100644 index 00000000..0892990b --- /dev/null +++ b/web/image/flags/sm.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/sn.svg b/web/image/flags/sn.svg new file mode 100644 index 00000000..7c0673d6 --- /dev/null +++ b/web/image/flags/sn.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/so.svg b/web/image/flags/so.svg new file mode 100644 index 00000000..4d4337af --- /dev/null +++ b/web/image/flags/so.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/image/flags/sr.svg b/web/image/flags/sr.svg new file mode 100644 index 00000000..5e71c400 --- /dev/null +++ b/web/image/flags/sr.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/ss.svg b/web/image/flags/ss.svg new file mode 100644 index 00000000..73804d80 --- /dev/null +++ b/web/image/flags/ss.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/st.svg b/web/image/flags/st.svg new file mode 100644 index 00000000..2259f318 --- /dev/null +++ b/web/image/flags/st.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/image/flags/sv.svg b/web/image/flags/sv.svg new file mode 100644 index 00000000..752dd3d4 --- /dev/null +++ b/web/image/flags/sv.svg @@ -0,0 +1,594 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/sx.svg b/web/image/flags/sx.svg new file mode 100644 index 00000000..bcc90d66 --- /dev/null +++ b/web/image/flags/sx.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/sy.svg b/web/image/flags/sy.svg new file mode 100644 index 00000000..29636ae0 --- /dev/null +++ b/web/image/flags/sy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/sz.svg b/web/image/flags/sz.svg new file mode 100644 index 00000000..02ef495a --- /dev/null +++ b/web/image/flags/sz.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/ta.svg b/web/image/flags/ta.svg new file mode 100644 index 00000000..b68ad23c --- /dev/null +++ b/web/image/flags/ta.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/tc.svg b/web/image/flags/tc.svg new file mode 100644 index 00000000..dbdb7168 --- /dev/null +++ b/web/image/flags/tc.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/td.svg b/web/image/flags/td.svg new file mode 100644 index 00000000..9fadf85a --- /dev/null +++ b/web/image/flags/td.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/tf.svg b/web/image/flags/tf.svg new file mode 100644 index 00000000..4572f4ee --- /dev/null +++ b/web/image/flags/tf.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/tg.svg b/web/image/flags/tg.svg new file mode 100644 index 00000000..8d763cb4 --- /dev/null +++ b/web/image/flags/tg.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/image/flags/th.svg b/web/image/flags/th.svg new file mode 100644 index 00000000..1e93a61e --- /dev/null +++ b/web/image/flags/th.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/tj.svg b/web/image/flags/tj.svg new file mode 100644 index 00000000..563c97b6 --- /dev/null +++ b/web/image/flags/tj.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/tk.svg b/web/image/flags/tk.svg new file mode 100644 index 00000000..65bab137 --- /dev/null +++ b/web/image/flags/tk.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/tl.svg b/web/image/flags/tl.svg new file mode 100644 index 00000000..1f11e925 --- /dev/null +++ b/web/image/flags/tl.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/tm.svg b/web/image/flags/tm.svg new file mode 100644 index 00000000..3c72f09d --- /dev/null +++ b/web/image/flags/tm.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/tn.svg b/web/image/flags/tn.svg new file mode 100644 index 00000000..73676881 --- /dev/null +++ b/web/image/flags/tn.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/to.svg b/web/image/flags/to.svg new file mode 100644 index 00000000..d0723370 --- /dev/null +++ b/web/image/flags/to.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/image/flags/tr.svg b/web/image/flags/tr.svg new file mode 100644 index 00000000..a92804f8 --- /dev/null +++ b/web/image/flags/tr.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/tt.svg b/web/image/flags/tt.svg new file mode 100644 index 00000000..14adbe04 --- /dev/null +++ b/web/image/flags/tt.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/image/flags/tv.svg b/web/image/flags/tv.svg new file mode 100644 index 00000000..675210ec --- /dev/null +++ b/web/image/flags/tv.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/image/flags/tw.svg b/web/image/flags/tw.svg new file mode 100644 index 00000000..78f3b9d4 --- /dev/null +++ b/web/image/flags/tw.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/tz.svg b/web/image/flags/tz.svg new file mode 100644 index 00000000..ca74eeca --- /dev/null +++ b/web/image/flags/tz.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/web/image/flags/ua.svg b/web/image/flags/ua.svg new file mode 100644 index 00000000..a339eb1b --- /dev/null +++ b/web/image/flags/ua.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/image/flags/ug.svg b/web/image/flags/ug.svg new file mode 100644 index 00000000..f9c5e1b2 --- /dev/null +++ b/web/image/flags/ug.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/um.svg b/web/image/flags/um.svg new file mode 100644 index 00000000..7b918389 --- /dev/null +++ b/web/image/flags/um.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/web/image/flags/un.svg b/web/image/flags/un.svg new file mode 100644 index 00000000..b04c3c43 --- /dev/null +++ b/web/image/flags/un.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/image/flags/us.svg b/web/image/flags/us.svg new file mode 100644 index 00000000..73b62457 --- /dev/null +++ b/web/image/flags/us.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/image/flags/uy.svg b/web/image/flags/uy.svg new file mode 100644 index 00000000..1634d71b --- /dev/null +++ b/web/image/flags/uy.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/uz.svg b/web/image/flags/uz.svg new file mode 100644 index 00000000..8c6a5324 --- /dev/null +++ b/web/image/flags/uz.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/va.svg b/web/image/flags/va.svg new file mode 100644 index 00000000..6a03dc46 --- /dev/null +++ b/web/image/flags/va.svg @@ -0,0 +1,479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/vc.svg b/web/image/flags/vc.svg new file mode 100644 index 00000000..450f6f0a --- /dev/null +++ b/web/image/flags/vc.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/ve.svg b/web/image/flags/ve.svg new file mode 100644 index 00000000..77bb549e --- /dev/null +++ b/web/image/flags/ve.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/vg.svg b/web/image/flags/vg.svg new file mode 100644 index 00000000..39023a93 --- /dev/null +++ b/web/image/flags/vg.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/vi.svg b/web/image/flags/vi.svg new file mode 100644 index 00000000..8a0941fa --- /dev/null +++ b/web/image/flags/vi.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/vn.svg b/web/image/flags/vn.svg new file mode 100644 index 00000000..c557e3af --- /dev/null +++ b/web/image/flags/vn.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/image/flags/vu.svg b/web/image/flags/vu.svg new file mode 100644 index 00000000..32f43779 --- /dev/null +++ b/web/image/flags/vu.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/wf.svg b/web/image/flags/wf.svg new file mode 100644 index 00000000..b0cc4c73 --- /dev/null +++ b/web/image/flags/wf.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/ws.svg b/web/image/flags/ws.svg new file mode 100644 index 00000000..0e758a7a --- /dev/null +++ b/web/image/flags/ws.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/xk.svg b/web/image/flags/xk.svg new file mode 100644 index 00000000..0edc0c7c --- /dev/null +++ b/web/image/flags/xk.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/image/flags/xx.svg b/web/image/flags/xx.svg new file mode 100644 index 00000000..34515ce7 --- /dev/null +++ b/web/image/flags/xx.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/image/flags/ye.svg b/web/image/flags/ye.svg new file mode 100644 index 00000000..61f0ed61 --- /dev/null +++ b/web/image/flags/ye.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/yt.svg b/web/image/flags/yt.svg new file mode 100644 index 00000000..e84f439a --- /dev/null +++ b/web/image/flags/yt.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/image/flags/za.svg b/web/image/flags/za.svg new file mode 100644 index 00000000..0c1f3aff --- /dev/null +++ b/web/image/flags/za.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/zm.svg b/web/image/flags/zm.svg new file mode 100644 index 00000000..84c99c2e --- /dev/null +++ b/web/image/flags/zm.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/flags/zw.svg b/web/image/flags/zw.svg new file mode 100644 index 00000000..64e8d483 --- /dev/null +++ b/web/image/flags/zw.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/web/image/os/android.svg b/web/image/os/android.svg new file mode 100644 index 00000000..d29cca80 --- /dev/null +++ b/web/image/os/android.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/arch.svg b/web/image/os/arch.svg new file mode 100644 index 00000000..bbc3a073 --- /dev/null +++ b/web/image/os/arch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/archlinux.svg b/web/image/os/archlinux.svg new file mode 100644 index 00000000..bbc3a073 --- /dev/null +++ b/web/image/os/archlinux.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/centos.svg b/web/image/os/centos.svg new file mode 100644 index 00000000..61be9e56 --- /dev/null +++ b/web/image/os/centos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/debian.svg b/web/image/os/debian.svg new file mode 100644 index 00000000..74d9d995 --- /dev/null +++ b/web/image/os/debian.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/linux.svg b/web/image/os/linux.svg new file mode 100644 index 00000000..bea317f2 --- /dev/null +++ b/web/image/os/linux.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/macos.svg b/web/image/os/macos.svg new file mode 100644 index 00000000..c24c4152 --- /dev/null +++ b/web/image/os/macos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/raspberry.svg b/web/image/os/raspberry.svg new file mode 100644 index 00000000..d7d47ca8 --- /dev/null +++ b/web/image/os/raspberry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/ubuntu.svg b/web/image/os/ubuntu.svg new file mode 100644 index 00000000..85be9798 --- /dev/null +++ b/web/image/os/ubuntu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/image/os/window.svg b/web/image/os/window.svg new file mode 100644 index 00000000..52a0ccad --- /dev/null +++ b/web/image/os/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/index.html b/web/index.html index 7c175dde..ed68d630 100644 --- a/web/index.html +++ b/web/index.html @@ -52,6 +52,7 @@ diff --git a/web/index3.html b/web/index3.html new file mode 100644 index 00000000..2f37a01b --- /dev/null +++ b/web/index3.html @@ -0,0 +1,29 @@ + + + + + + + ServerStatus + + + + + + +
+

+ Light Default +

+
+
+ Powered by ServerStatus-Rust. + Theme Light by OriLight +
+
+ + + + From 59fa2d8eabafaac5c311a3a7ff753fabd3e11aaa Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 17 Oct 2023 01:46:19 +0000 Subject: [PATCH 017/134] fix light bug --- web/assets/index-982ea826.js | 1 - web/assets/index-e069a4f0.js | 1 + web/index3.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 web/assets/index-982ea826.js create mode 100644 web/assets/index-e069a4f0.js diff --git a/web/assets/index-982ea826.js b/web/assets/index-982ea826.js deleted file mode 100644 index 2cfe3cb4..00000000 --- a/web/assets/index-982ea826.js +++ /dev/null @@ -1 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))r(n);new MutationObserver(n=>{for(const o of n)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&r(l)}).observe(document,{childList:!0,subtree:!0});function s(n){const o={};return n.integrity&&(o.integrity=n.integrity),n.referrerPolicy&&(o.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?o.credentials="include":n.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(n){if(n.ep)return;n.ep=!0;const o=s(n);fetch(n.href,o)}})();function Is(e,t){const s=Object.create(null),r=e.split(",");for(let n=0;n!!s[n.toLowerCase()]:n=>!!s[n]}const K={},Qe=[],be=()=>{},Fr=()=>!1,Ar=/^on[^a-z]/,zt=e=>Ar.test(e),Ms=e=>e.startsWith("onUpdate:"),G=Object.assign,Fs=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$r=Object.prototype.hasOwnProperty,S=(e,t)=>$r.call(e,t),P=Array.isArray,Ge=e=>qt(e)==="[object Map]",$n=e=>qt(e)==="[object Set]",M=e=>typeof e=="function",V=e=>typeof e=="string",As=e=>typeof e=="symbol",W=e=>e!==null&&typeof e=="object",Rn=e=>W(e)&&M(e.then)&&M(e.catch),Sn=Object.prototype.toString,qt=e=>Sn.call(e),Rr=e=>qt(e).slice(8,-1),jn=e=>qt(e)==="[object Object]",$s=e=>V(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Bt=Is(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Yt=e=>{const t=Object.create(null);return s=>t[s]||(t[s]=e(s))},Sr=/-(\w)/g,st=Yt(e=>e.replace(Sr,(t,s)=>s?s.toUpperCase():"")),jr=/\B([A-Z])/g,lt=Yt(e=>e.replace(jr,"-$1").toLowerCase()),Nn=Yt(e=>e.charAt(0).toUpperCase()+e.slice(1)),ls=Yt(e=>e?`on${Nn(e)}`:""),bt=(e,t)=>!Object.is(e,t),is=(e,t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:s})},Nr=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let tn;const gs=()=>tn||(tn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Jt(e){if(P(e)){const t={};for(let s=0;s{if(s){const r=s.split(Dr);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function it(e){let t="";if(V(e))t=e;else if(P(e))for(let s=0;sV(e)?e:e==null?"":P(e)||W(e)&&(e.toString===Sn||!M(e.toString))?JSON.stringify(e,Dn,2):String(e),Dn=(e,t)=>t&&t.__v_isRef?Dn(e,t.value):Ge(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[r,n])=>(s[`${r} =>`]=n,s),{})}:$n(t)?{[`Set(${t.size})`]:[...t.values()]}:W(t)&&!P(t)&&!jn(t)?String(t):t;let _e;class kr{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=_e,!t&&_e&&(this.index=(_e.scopes||(_e.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const s=_e;try{return _e=this,t()}finally{_e=s}}}on(){_e=this}off(){_e=this.parent}stop(t){if(this._active){let s,r;for(s=0,r=this.effects.length;s{const t=new Set(e);return t.w=0,t.n=0,t},Hn=e=>(e.w&Ne)>0,Ln=e=>(e.n&Ne)>0,qr=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let s=0;for(let r=0;r{(g==="length"||g>=u)&&c.push(a)})}else switch(s!==void 0&&c.push(l.get(s)),t){case"add":P(e)?$s(s)&&c.push(l.get("length")):(c.push(l.get(qe)),Ge(e)&&c.push(l.get(vs)));break;case"delete":P(e)||(c.push(l.get(qe)),Ge(e)&&c.push(l.get(vs)));break;case"set":Ge(e)&&c.push(l.get(qe));break}if(c.length===1)c[0]&&bs(c[0]);else{const u=[];for(const a of c)a&&u.push(...a);bs(Rs(u))}}function bs(e,t){const s=P(e)?e:[...e];for(const r of s)r.computed&&nn(r);for(const r of s)r.computed||nn(r)}function nn(e,t){(e!==me||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}const Jr=Is("__proto__,__v_isRef,__isVue"),kn=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(As)),Zr=js(),Vr=js(!1,!0),Xr=js(!0),rn=Qr();function Qr(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...s){const r=N(this);for(let o=0,l=this.length;o{e[t]=function(...s){ct();const r=N(this)[t].apply(this,s);return ft(),r}}),e}function Gr(e){const t=N(this);return ae(t,"has",e),t.hasOwnProperty(e)}function js(e=!1,t=!1){return function(r,n,o){if(n==="__v_isReactive")return!e;if(n==="__v_isReadonly")return e;if(n==="__v_isShallow")return t;if(n==="__v_raw"&&o===(e?t?_o:Jn:t?Yn:qn).get(r))return r;const l=P(r);if(!e){if(l&&S(rn,n))return Reflect.get(rn,n,o);if(n==="hasOwnProperty")return Gr}const c=Reflect.get(r,n,o);return(As(n)?kn.has(n):Jr(n))||(e||ae(r,"get",n),t)?c:le(c)?l&&$s(n)?c:c.value:W(c)?e?Zn(c):Ds(c):c}}const eo=Wn(),to=Wn(!0);function Wn(e=!1){return function(s,r,n,o){let l=s[r];if(nt(l)&&le(l)&&!le(n))return!1;if(!e&&(!Ut(n)&&!nt(n)&&(l=N(l),n=N(n)),!P(s)&&le(l)&&!le(n)))return l.value=n,!0;const c=P(s)&&$s(r)?Number(r)e,Zt=e=>Reflect.getPrototypeOf(e);function Ft(e,t,s=!1,r=!1){e=e.__v_raw;const n=N(e),o=N(t);s||(t!==o&&ae(n,"get",t),ae(n,"get",o));const{has:l}=Zt(n),c=r?Ns:s?Ls:yt;if(l.call(n,t))return c(e.get(t));if(l.call(n,o))return c(e.get(o));e!==n&&e.get(t)}function At(e,t=!1){const s=this.__v_raw,r=N(s),n=N(e);return t||(e!==n&&ae(r,"has",e),ae(r,"has",n)),e===n?s.has(e):s.has(e)||s.has(n)}function $t(e,t=!1){return e=e.__v_raw,!t&&ae(N(e),"iterate",qe),Reflect.get(e,"size",e)}function on(e){e=N(e);const t=N(this);return Zt(t).has.call(t,e)||(t.add(e),Me(t,"add",e,e)),this}function ln(e,t){t=N(t);const s=N(this),{has:r,get:n}=Zt(s);let o=r.call(s,e);o||(e=N(e),o=r.call(s,e));const l=n.call(s,e);return s.set(e,t),o?bt(t,l)&&Me(s,"set",e,t):Me(s,"add",e,t),this}function cn(e){const t=N(this),{has:s,get:r}=Zt(t);let n=s.call(t,e);n||(e=N(e),n=s.call(t,e)),r&&r.call(t,e);const o=t.delete(e);return n&&Me(t,"delete",e,void 0),o}function fn(){const e=N(this),t=e.size!==0,s=e.clear();return t&&Me(e,"clear",void 0,void 0),s}function Rt(e,t){return function(r,n){const o=this,l=o.__v_raw,c=N(l),u=t?Ns:e?Ls:yt;return!e&&ae(c,"iterate",qe),l.forEach((a,g)=>r.call(n,u(a),u(g),o))}}function St(e,t,s){return function(...r){const n=this.__v_raw,o=N(n),l=Ge(o),c=e==="entries"||e===Symbol.iterator&&l,u=e==="keys"&&l,a=n[e](...r),g=s?Ns:t?Ls:yt;return!t&&ae(o,"iterate",u?vs:qe),{next(){const{value:x,done:E}=a.next();return E?{value:x,done:E}:{value:c?[g(x[0]),g(x[1])]:g(x),done:E}},[Symbol.iterator](){return this}}}}function $e(e){return function(...t){return e==="delete"?!1:this}}function io(){const e={get(o){return Ft(this,o)},get size(){return $t(this)},has:At,add:on,set:ln,delete:cn,clear:fn,forEach:Rt(!1,!1)},t={get(o){return Ft(this,o,!1,!0)},get size(){return $t(this)},has:At,add:on,set:ln,delete:cn,clear:fn,forEach:Rt(!1,!0)},s={get(o){return Ft(this,o,!0)},get size(){return $t(this,!0)},has(o){return At.call(this,o,!0)},add:$e("add"),set:$e("set"),delete:$e("delete"),clear:$e("clear"),forEach:Rt(!0,!1)},r={get(o){return Ft(this,o,!0,!0)},get size(){return $t(this,!0)},has(o){return At.call(this,o,!0)},add:$e("add"),set:$e("set"),delete:$e("delete"),clear:$e("clear"),forEach:Rt(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=St(o,!1,!1),s[o]=St(o,!0,!1),t[o]=St(o,!1,!0),r[o]=St(o,!0,!0)}),[e,s,t,r]}const[co,fo,uo,ao]=io();function Bs(e,t){const s=t?e?ao:uo:e?fo:co;return(r,n,o)=>n==="__v_isReactive"?!e:n==="__v_isReadonly"?e:n==="__v_raw"?r:Reflect.get(S(s,n)&&n in r?s:r,n,o)}const ho={get:Bs(!1,!1)},po={get:Bs(!1,!0)},go={get:Bs(!0,!1)},qn=new WeakMap,Yn=new WeakMap,Jn=new WeakMap,_o=new WeakMap;function mo(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function vo(e){return e.__v_skip||!Object.isExtensible(e)?0:mo(Rr(e))}function Ds(e){return nt(e)?e:Hs(e,!1,zn,ho,qn)}function bo(e){return Hs(e,!1,lo,po,Yn)}function Zn(e){return Hs(e,!0,oo,go,Jn)}function Hs(e,t,s,r,n){if(!W(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=n.get(e);if(o)return o;const l=vo(e);if(l===0)return e;const c=new Proxy(e,l===2?r:s);return n.set(e,c),c}function et(e){return nt(e)?et(e.__v_raw):!!(e&&e.__v_isReactive)}function nt(e){return!!(e&&e.__v_isReadonly)}function Ut(e){return!!(e&&e.__v_isShallow)}function Vn(e){return et(e)||nt(e)}function N(e){const t=e&&e.__v_raw;return t?N(t):e}function Xn(e){return Lt(e,"__v_skip",!0),e}const yt=e=>W(e)?Ds(e):e,Ls=e=>W(e)?Zn(e):e;function Qn(e){Se&&me&&(e=N(e),Kn(e.dep||(e.dep=Rs())))}function Gn(e,t){e=N(e);const s=e.dep;s&&bs(s)}function le(e){return!!(e&&e.__v_isRef===!0)}function jt(e){return yo(e,!1)}function yo(e,t){return le(e)?e:new xo(e,t)}class xo{constructor(t,s){this.__v_isShallow=s,this.dep=void 0,this.__v_isRef=!0,this._rawValue=s?t:N(t),this._value=s?t:yt(t)}get value(){return Qn(this),this._value}set value(t){const s=this.__v_isShallow||Ut(t)||nt(t);t=s?t:N(t),bt(t,this._rawValue)&&(this._rawValue=t,this._value=s?t:yt(t),Gn(this))}}function U(e){return le(e)?e.value:e}const wo={get:(e,t,s)=>U(Reflect.get(e,t,s)),set:(e,t,s,r)=>{const n=e[t];return le(n)&&!le(s)?(n.value=s,!0):Reflect.set(e,t,s,r)}};function er(e){return et(e)?e:new Proxy(e,wo)}class Eo{constructor(t,s,r,n){this._setter=s,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new Ss(t,()=>{this._dirty||(this._dirty=!0,Gn(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!n,this.__v_isReadonly=r}get value(){const t=N(this);return Qn(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function Co(e,t,s=!1){let r,n;const o=M(e);return o?(r=e,n=be):(r=e.get,n=e.set),new Eo(r,n,o||!n,s)}function je(e,t,s,r){let n;try{n=r?e(...r):e()}catch(o){Vt(o,t,s)}return n}function ye(e,t,s,r){if(M(e)){const o=je(e,t,s,r);return o&&Rn(o)&&o.catch(l=>{Vt(l,t,s)}),o}const n=[];for(let o=0;o>>1;wt(re[r])Te&&re.splice(t,1)}function Mo(e){P(e)?tt.push(...e):(!Ie||!Ie.includes(e,e.allowRecurse?We+1:We))&&tt.push(e),sr()}function un(e,t=xt?Te+1:0){for(;twt(s)-wt(r)),We=0;Wee.id==null?1/0:e.id,Fo=(e,t)=>{const s=wt(e)-wt(t);if(s===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return s};function rr(e){ys=!1,xt=!0,re.sort(Fo);const t=be;try{for(Te=0;TeV(I)?I.trim():I)),x&&(n=s.map(Nr))}let c,u=r[c=ls(t)]||r[c=ls(st(t))];!u&&o&&(u=r[c=ls(lt(t))]),u&&ye(u,e,6,n);const a=r[c+"Once"];if(a){if(!e.emitted)e.emitted={};else if(e.emitted[c])return;e.emitted[c]=!0,ye(a,e,6,n)}}function or(e,t,s=!1){const r=t.emitsCache,n=r.get(e);if(n!==void 0)return n;const o=e.emits;let l={},c=!1;if(!M(e)){const u=a=>{const g=or(a,t,!0);g&&(c=!0,G(l,g))};!s&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}return!o&&!c?(W(e)&&r.set(e,null),null):(P(o)?o.forEach(u=>l[u]=null):G(l,o),W(e)&&r.set(e,l),l)}function Xt(e,t){return!e||!zt(t)?!1:(t=t.slice(2).replace(/Once$/,""),S(e,t[0].toLowerCase()+t.slice(1))||S(e,lt(t))||S(e,t))}let ue=null,lr=null;function Kt(e){const t=ue;return ue=e,lr=e&&e.type.__scopeId||null,t}function Q(e,t=ue,s){if(!t||e._n)return e;const r=(...n)=>{r._d&&yn(-1);const o=Kt(t);let l;try{l=e(...n)}finally{Kt(o),r._d&&yn(1)}return l};return r._n=!0,r._c=!0,r._d=!0,r}function cs(e){const{type:t,vnode:s,proxy:r,withProxy:n,props:o,propsOptions:[l],slots:c,attrs:u,emit:a,render:g,renderCache:x,data:E,setupState:I,ctx:Y,inheritAttrs:$}=e;let X,te;const se=Kt(e);try{if(s.shapeFlag&4){const F=n||r;X=Oe(g.call(F,F,x,o,I,E,Y)),te=u}else{const F=t;X=Oe(F.length>1?F(o,{attrs:u,slots:c,emit:a}):F(o,null)),te=t.props?u:$o(u)}}catch(F){vt.length=0,Vt(F,e,1),X=L(Be)}let ne=X;if(te&&$!==!1){const F=Object.keys(te),{shapeFlag:Ae}=ne;F.length&&Ae&7&&(l&&F.some(Ms)&&(te=Ro(te,l)),ne=rt(ne,te))}return s.dirs&&(ne=rt(ne),ne.dirs=ne.dirs?ne.dirs.concat(s.dirs):s.dirs),s.transition&&(ne.transition=s.transition),X=ne,Kt(se),X}const $o=e=>{let t;for(const s in e)(s==="class"||s==="style"||zt(s))&&((t||(t={}))[s]=e[s]);return t},Ro=(e,t)=>{const s={};for(const r in e)(!Ms(r)||!(r.slice(9)in t))&&(s[r]=e[r]);return s};function So(e,t,s){const{props:r,children:n,component:o}=e,{props:l,children:c,patchFlag:u}=t,a=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&u>=0){if(u&1024)return!0;if(u&16)return r?an(r,l,a):!!l;if(u&8){const g=t.dynamicProps;for(let x=0;xe.__isSuspense;function Bo(e,t){t&&t.pendingBranch?P(e)?t.effects.push(...e):t.effects.push(e):Mo(e)}const Nt={};function fs(e,t,s){return ir(e,t,s)}function ir(e,t,{immediate:s,deep:r,flush:n,onTrack:o,onTrigger:l}=K){var c;const u=zr()===((c=oe)==null?void 0:c.scope)?oe:null;let a,g=!1,x=!1;if(le(e)?(a=()=>e.value,g=Ut(e)):et(e)?(a=()=>e,r=!0):P(e)?(x=!0,g=e.some(F=>et(F)||Ut(F)),a=()=>e.map(F=>{if(le(F))return F.value;if(et(F))return Xe(F);if(M(F))return je(F,u,2)})):M(e)?t?a=()=>je(e,u,2):a=()=>{if(!(u&&u.isUnmounted))return E&&E(),ye(e,u,3,[I])}:a=be,t&&r){const F=a;a=()=>Xe(F())}let E,I=F=>{E=se.onStop=()=>{je(F,u,4)}},Y;if(Ct)if(I=be,t?s&&ye(t,u,3,[a(),x?[]:void 0,I]):a(),n==="sync"){const F=Ml();Y=F.__watcherHandles||(F.__watcherHandles=[])}else return be;let $=x?new Array(e.length).fill(Nt):Nt;const X=()=>{if(se.active)if(t){const F=se.run();(r||g||(x?F.some((Ae,ut)=>bt(Ae,$[ut])):bt(F,$)))&&(E&&E(),ye(t,u,3,[F,$===Nt?void 0:x&&$[0]===Nt?[]:$,I]),$=F)}else se.run()};X.allowRecurse=!!t;let te;n==="sync"?te=X:n==="post"?te=()=>fe(X,u&&u.suspense):(X.pre=!0,u&&(X.id=u.uid),te=()=>Ks(X));const se=new Ss(a,te);t?s?X():$=se.run():n==="post"?fe(se.run.bind(se),u&&u.suspense):se.run();const ne=()=>{se.stop(),u&&u.scope&&Fs(u.scope.effects,se)};return Y&&Y.push(ne),ne}function Do(e,t,s){const r=this.proxy,n=V(e)?e.includes(".")?cr(r,e):()=>r[e]:e.bind(r,r);let o;M(t)?o=t:(o=t.handler,s=t);const l=oe;ot(this);const c=ir(n,o.bind(r),s);return l?ot(l):Ye(),c}function cr(e,t){const s=t.split(".");return()=>{let r=e;for(let n=0;n{Xe(s,t)});else if(jn(e))for(const s in e)Xe(e[s],t);return e}function Ke(e,t,s,r){const n=e.dirs,o=t&&t.dirs;for(let l=0;lG({name:e.name},t,{setup:e}))():e}const _t=e=>!!e.type.__asyncLoader,fr=e=>e.type.__isKeepAlive;function Ho(e,t){ur(e,"a",t)}function Lo(e,t){ur(e,"da",t)}function ur(e,t,s=oe){const r=e.__wdc||(e.__wdc=()=>{let n=s;for(;n;){if(n.isDeactivated)return;n=n.parent}return e()});if(Gt(t,r,s),s){let n=s.parent;for(;n&&n.parent;)fr(n.parent.vnode)&&Uo(r,t,s,n),n=n.parent}}function Uo(e,t,s,r){const n=Gt(t,e,r,!0);dr(()=>{Fs(r[t],n)},s)}function Gt(e,t,s=oe,r=!1){if(s){const n=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...l)=>{if(s.isUnmounted)return;ct(),ot(s);const c=ye(t,s,e,l);return Ye(),ft(),c});return r?n.unshift(o):n.push(o),o}}const Fe=e=>(t,s=oe)=>(!Ct||e==="sp")&&Gt(e,(...r)=>t(...r),s),Ko=Fe("bm"),ar=Fe("m"),ko=Fe("bu"),Wo=Fe("u"),zo=Fe("bum"),dr=Fe("um"),qo=Fe("sp"),Yo=Fe("rtg"),Jo=Fe("rtc");function Zo(e,t=oe){Gt("ec",e,t)}const Vo=Symbol.for("v-ndc");function Xo(e,t,s,r){let n;const o=s&&s[r];if(P(e)||V(e)){n=new Array(e.length);for(let l=0,c=e.length;lt(l,c,void 0,o&&o[c]));else{const l=Object.keys(e);n=new Array(l.length);for(let c=0,u=l.length;cCr(t)?!(t.type===Be||t.type===he&&!pr(t.children)):!0)?e:null}const xs=e=>e?Tr(e)?Ys(e)||e.proxy:xs(e.parent):null,mt=G(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>xs(e.parent),$root:e=>xs(e.root),$emit:e=>e.emit,$options:e=>ks(e),$forceUpdate:e=>e.f||(e.f=()=>Ks(e.update)),$nextTick:e=>e.n||(e.n=To.bind(e.proxy)),$watch:e=>Do.bind(e)}),us=(e,t)=>e!==K&&!e.__isScriptSetup&&S(e,t),Qo={get({_:e},t){const{ctx:s,setupState:r,data:n,props:o,accessCache:l,type:c,appContext:u}=e;let a;if(t[0]!=="$"){const I=l[t];if(I!==void 0)switch(I){case 1:return r[t];case 2:return n[t];case 4:return s[t];case 3:return o[t]}else{if(us(r,t))return l[t]=1,r[t];if(n!==K&&S(n,t))return l[t]=2,n[t];if((a=e.propsOptions[0])&&S(a,t))return l[t]=3,o[t];if(s!==K&&S(s,t))return l[t]=4,s[t];ws&&(l[t]=0)}}const g=mt[t];let x,E;if(g)return t==="$attrs"&&ae(e,"get",t),g(e);if((x=c.__cssModules)&&(x=x[t]))return x;if(s!==K&&S(s,t))return l[t]=4,s[t];if(E=u.config.globalProperties,S(E,t))return E[t]},set({_:e},t,s){const{data:r,setupState:n,ctx:o}=e;return us(n,t)?(n[t]=s,!0):r!==K&&S(r,t)?(r[t]=s,!0):S(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:r,appContext:n,propsOptions:o}},l){let c;return!!s[l]||e!==K&&S(e,l)||us(t,l)||(c=o[0])&&S(c,l)||S(r,l)||S(mt,l)||S(n.config.globalProperties,l)},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:S(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function dn(e){return P(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let ws=!0;function Go(e){const t=ks(e),s=e.proxy,r=e.ctx;ws=!1,t.beforeCreate&&hn(t.beforeCreate,e,"bc");const{data:n,computed:o,methods:l,watch:c,provide:u,inject:a,created:g,beforeMount:x,mounted:E,beforeUpdate:I,updated:Y,activated:$,deactivated:X,beforeDestroy:te,beforeUnmount:se,destroyed:ne,unmounted:F,render:Ae,renderTracked:ut,renderTriggered:Ot,errorCaptured:De,serverPrefetch:ss,expose:He,inheritAttrs:at,components:Tt,directives:Pt,filters:ns}=t;if(a&&el(a,r,null),l)for(const z in l){const D=l[z];M(D)&&(r[z]=D.bind(s))}if(n){const z=n.call(s,s);W(z)&&(e.data=Ds(z))}if(ws=!0,o)for(const z in o){const D=o[z],Le=M(D)?D.bind(s,s):M(D.get)?D.get.bind(s,s):be,It=!M(D)&&M(D.set)?D.set.bind(s):be,Ue=Ts({get:Le,set:It});Object.defineProperty(r,z,{enumerable:!0,configurable:!0,get:()=>Ue.value,set:xe=>Ue.value=xe})}if(c)for(const z in c)gr(c[z],r,s,z);if(u){const z=M(u)?u.call(s):u;Reflect.ownKeys(z).forEach(D=>{ll(D,z[D])})}g&&hn(g,e,"c");function ie(z,D){P(D)?D.forEach(Le=>z(Le.bind(s))):D&&z(D.bind(s))}if(ie(Ko,x),ie(ar,E),ie(ko,I),ie(Wo,Y),ie(Ho,$),ie(Lo,X),ie(Zo,De),ie(Jo,ut),ie(Yo,Ot),ie(zo,se),ie(dr,F),ie(qo,ss),P(He))if(He.length){const z=e.exposed||(e.exposed={});He.forEach(D=>{Object.defineProperty(z,D,{get:()=>s[D],set:Le=>s[D]=Le})})}else e.exposed||(e.exposed={});Ae&&e.render===be&&(e.render=Ae),at!=null&&(e.inheritAttrs=at),Tt&&(e.components=Tt),Pt&&(e.directives=Pt)}function el(e,t,s=be){P(e)&&(e=Es(e));for(const r in e){const n=e[r];let o;W(n)?"default"in n?o=Dt(n.from||r,n.default,!0):o=Dt(n.from||r):o=Dt(n),le(o)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>o.value,set:l=>o.value=l}):t[r]=o}}function hn(e,t,s){ye(P(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,s)}function gr(e,t,s,r){const n=r.includes(".")?cr(s,r):()=>s[r];if(V(e)){const o=t[e];M(o)&&fs(n,o)}else if(M(e))fs(n,e.bind(s));else if(W(e))if(P(e))e.forEach(o=>gr(o,t,s,r));else{const o=M(e.handler)?e.handler.bind(s):t[e.handler];M(o)&&fs(n,o,e)}}function ks(e){const t=e.type,{mixins:s,extends:r}=t,{mixins:n,optionsCache:o,config:{optionMergeStrategies:l}}=e.appContext,c=o.get(t);let u;return c?u=c:!n.length&&!s&&!r?u=t:(u={},n.length&&n.forEach(a=>kt(u,a,l,!0)),kt(u,t,l)),W(t)&&o.set(t,u),u}function kt(e,t,s,r=!1){const{mixins:n,extends:o}=t;o&&kt(e,o,s,!0),n&&n.forEach(l=>kt(e,l,s,!0));for(const l in t)if(!(r&&l==="expose")){const c=tl[l]||s&&s[l];e[l]=c?c(e[l],t[l]):t[l]}return e}const tl={data:pn,props:gn,emits:gn,methods:gt,computed:gt,beforeCreate:ce,created:ce,beforeMount:ce,mounted:ce,beforeUpdate:ce,updated:ce,beforeDestroy:ce,beforeUnmount:ce,destroyed:ce,unmounted:ce,activated:ce,deactivated:ce,errorCaptured:ce,serverPrefetch:ce,components:gt,directives:gt,watch:nl,provide:pn,inject:sl};function pn(e,t){return t?e?function(){return G(M(e)?e.call(this,this):e,M(t)?t.call(this,this):t)}:t:e}function sl(e,t){return gt(Es(e),Es(t))}function Es(e){if(P(e)){const t={};for(let s=0;s1)return s&&M(t)?t.call(r&&r.proxy):t}}function il(e,t,s,r=!1){const n={},o={};Lt(o,ts,1),e.propsDefaults=Object.create(null),mr(e,t,n,o);for(const l in e.propsOptions[0])l in n||(n[l]=void 0);s?e.props=r?n:bo(n):e.type.props?e.props=n:e.props=o,e.attrs=o}function cl(e,t,s,r){const{props:n,attrs:o,vnode:{patchFlag:l}}=e,c=N(n),[u]=e.propsOptions;let a=!1;if((r||l>0)&&!(l&16)){if(l&8){const g=e.vnode.dynamicProps;for(let x=0;x{u=!0;const[E,I]=vr(x,t,!0);G(l,E),I&&c.push(...I)};!s&&t.mixins.length&&t.mixins.forEach(g),e.extends&&g(e.extends),e.mixins&&e.mixins.forEach(g)}if(!o&&!u)return W(e)&&r.set(e,Qe),Qe;if(P(o))for(let g=0;g-1,I[1]=$<0||Y<$,(Y>-1||S(I,"default"))&&c.push(x)}}}const a=[l,c];return W(e)&&r.set(e,a),a}function _n(e){return e[0]!=="$"}function mn(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function vn(e,t){return mn(e)===mn(t)}function bn(e,t){return P(t)?t.findIndex(s=>vn(s,e)):M(t)&&vn(t,e)?0:-1}const br=e=>e[0]==="_"||e==="$stable",Ws=e=>P(e)?e.map(Oe):[Oe(e)],fl=(e,t,s)=>{if(t._n)return t;const r=Q((...n)=>Ws(t(...n)),s);return r._c=!1,r},yr=(e,t,s)=>{const r=e._ctx;for(const n in e){if(br(n))continue;const o=e[n];if(M(o))t[n]=fl(n,o,r);else if(o!=null){const l=Ws(o);t[n]=()=>l}}},xr=(e,t)=>{const s=Ws(t);e.slots.default=()=>s},ul=(e,t)=>{if(e.vnode.shapeFlag&32){const s=t._;s?(e.slots=N(t),Lt(t,"_",s)):yr(t,e.slots={})}else e.slots={},t&&xr(e,t);Lt(e.slots,ts,1)},al=(e,t,s)=>{const{vnode:r,slots:n}=e;let o=!0,l=K;if(r.shapeFlag&32){const c=t._;c?s&&c===1?o=!1:(G(n,t),!s&&c===1&&delete n._):(o=!t.$stable,yr(t,n)),l=t}else t&&(xr(e,t),l={default:1});if(o)for(const c in n)!br(c)&&!(c in l)&&delete n[c]};function Os(e,t,s,r,n=!1){if(P(e)){e.forEach((E,I)=>Os(E,t&&(P(t)?t[I]:t),s,r,n));return}if(_t(r)&&!n)return;const o=r.shapeFlag&4?Ys(r.component)||r.component.proxy:r.el,l=n?null:o,{i:c,r:u}=e,a=t&&t.r,g=c.refs===K?c.refs={}:c.refs,x=c.setupState;if(a!=null&&a!==u&&(V(a)?(g[a]=null,S(x,a)&&(x[a]=null)):le(a)&&(a.value=null)),M(u))je(u,c,12,[l,g]);else{const E=V(u),I=le(u);if(E||I){const Y=()=>{if(e.f){const $=E?S(x,u)?x[u]:g[u]:u.value;n?P($)&&Fs($,o):P($)?$.includes(o)||$.push(o):E?(g[u]=[o],S(x,u)&&(x[u]=g[u])):(u.value=[o],e.k&&(g[e.k]=u.value))}else E?(g[u]=l,S(x,u)&&(x[u]=l)):I&&(u.value=l,e.k&&(g[e.k]=l))};l?(Y.id=-1,fe(Y,s)):Y()}}}const fe=Bo;function dl(e){return hl(e)}function hl(e,t){const s=gs();s.__VUE__=!0;const{insert:r,remove:n,patchProp:o,createElement:l,createText:c,createComment:u,setText:a,setElementText:g,parentNode:x,nextSibling:E,setScopeId:I=be,insertStaticContent:Y}=e,$=(i,f,d,p=null,h=null,v=null,y=!1,m=null,b=!!f.dynamicChildren)=>{if(i===f)return;i&&!ht(i,f)&&(p=Mt(i),xe(i,h,v,!0),i=null),f.patchFlag===-2&&(b=!1,f.dynamicChildren=null);const{type:_,ref:C,shapeFlag:w}=f;switch(_){case es:X(i,f,d,p);break;case Be:te(i,f,d,p);break;case as:i==null&&se(f,d,p,y);break;case he:Tt(i,f,d,p,h,v,y,m,b);break;default:w&1?Ae(i,f,d,p,h,v,y,m,b):w&6?Pt(i,f,d,p,h,v,y,m,b):(w&64||w&128)&&_.process(i,f,d,p,h,v,y,m,b,Je)}C!=null&&h&&Os(C,i&&i.ref,v,f||i,!f)},X=(i,f,d,p)=>{if(i==null)r(f.el=c(f.children),d,p);else{const h=f.el=i.el;f.children!==i.children&&a(h,f.children)}},te=(i,f,d,p)=>{i==null?r(f.el=u(f.children||""),d,p):f.el=i.el},se=(i,f,d,p)=>{[i.el,i.anchor]=Y(i.children,f,d,p,i.el,i.anchor)},ne=({el:i,anchor:f},d,p)=>{let h;for(;i&&i!==f;)h=E(i),r(i,d,p),i=h;r(f,d,p)},F=({el:i,anchor:f})=>{let d;for(;i&&i!==f;)d=E(i),n(i),i=d;n(f)},Ae=(i,f,d,p,h,v,y,m,b)=>{y=y||f.type==="svg",i==null?ut(f,d,p,h,v,y,m,b):ss(i,f,h,v,y,m,b)},ut=(i,f,d,p,h,v,y,m)=>{let b,_;const{type:C,props:w,shapeFlag:O,transition:T,dirs:A}=i;if(b=i.el=l(i.type,v,w&&w.is,w),O&8?g(b,i.children):O&16&&De(i.children,b,null,p,h,v&&C!=="foreignObject",y,m),A&&Ke(i,null,p,"created"),Ot(b,i,i.scopeId,y,p),w){for(const B in w)B!=="value"&&!Bt(B)&&o(b,B,null,w[B],v,i.children,p,h,Pe);"value"in w&&o(b,"value",null,w.value),(_=w.onVnodeBeforeMount)&&Ee(_,p,i)}A&&Ke(i,null,p,"beforeMount");const H=(!h||h&&!h.pendingBranch)&&T&&!T.persisted;H&&T.beforeEnter(b),r(b,f,d),((_=w&&w.onVnodeMounted)||H||A)&&fe(()=>{_&&Ee(_,p,i),H&&T.enter(b),A&&Ke(i,null,p,"mounted")},h)},Ot=(i,f,d,p,h)=>{if(d&&I(i,d),p)for(let v=0;v{for(let _=b;_{const m=f.el=i.el;let{patchFlag:b,dynamicChildren:_,dirs:C}=f;b|=i.patchFlag&16;const w=i.props||K,O=f.props||K;let T;d&&ke(d,!1),(T=O.onVnodeBeforeUpdate)&&Ee(T,d,f,i),C&&Ke(f,i,d,"beforeUpdate"),d&&ke(d,!0);const A=h&&f.type!=="foreignObject";if(_?He(i.dynamicChildren,_,m,d,p,A,v):y||D(i,f,m,null,d,p,A,v,!1),b>0){if(b&16)at(m,f,w,O,d,p,h);else if(b&2&&w.class!==O.class&&o(m,"class",null,O.class,h),b&4&&o(m,"style",w.style,O.style,h),b&8){const H=f.dynamicProps;for(let B=0;B{T&&Ee(T,d,f,i),C&&Ke(f,i,d,"updated")},p)},He=(i,f,d,p,h,v,y)=>{for(let m=0;m{if(d!==p){if(d!==K)for(const m in d)!Bt(m)&&!(m in p)&&o(i,m,d[m],null,y,f.children,h,v,Pe);for(const m in p){if(Bt(m))continue;const b=p[m],_=d[m];b!==_&&m!=="value"&&o(i,m,_,b,y,f.children,h,v,Pe)}"value"in p&&o(i,"value",d.value,p.value)}},Tt=(i,f,d,p,h,v,y,m,b)=>{const _=f.el=i?i.el:c(""),C=f.anchor=i?i.anchor:c("");let{patchFlag:w,dynamicChildren:O,slotScopeIds:T}=f;T&&(m=m?m.concat(T):T),i==null?(r(_,d,p),r(C,d,p),De(f.children,d,C,h,v,y,m,b)):w>0&&w&64&&O&&i.dynamicChildren?(He(i.dynamicChildren,O,d,h,v,y,m),(f.key!=null||h&&f===h.subTree)&&wr(i,f,!0)):D(i,f,d,C,h,v,y,m,b)},Pt=(i,f,d,p,h,v,y,m,b)=>{f.slotScopeIds=m,i==null?f.shapeFlag&512?h.ctx.activate(f,d,p,y,b):ns(f,d,p,h,v,y,b):Zs(i,f,b)},ns=(i,f,d,p,h,v,y)=>{const m=i.component=wl(i,p,h);if(fr(i)&&(m.ctx.renderer=Je),El(m),m.asyncDep){if(h&&h.registerDep(m,ie),!i.el){const b=m.subTree=L(Be);te(null,b,f,d)}return}ie(m,i,f,d,h,v,y)},Zs=(i,f,d)=>{const p=f.component=i.component;if(So(i,f,d))if(p.asyncDep&&!p.asyncResolved){z(p,f,d);return}else p.next=f,Io(p.update),p.update();else f.el=i.el,p.vnode=f},ie=(i,f,d,p,h,v,y)=>{const m=()=>{if(i.isMounted){let{next:C,bu:w,u:O,parent:T,vnode:A}=i,H=C,B;ke(i,!1),C?(C.el=A.el,z(i,C,y)):C=A,w&&is(w),(B=C.props&&C.props.onVnodeBeforeUpdate)&&Ee(B,T,C,A),ke(i,!0);const J=cs(i),ge=i.subTree;i.subTree=J,$(ge,J,x(ge.el),Mt(ge),i,h,v),C.el=J.el,H===null&&jo(i,J.el),O&&fe(O,h),(B=C.props&&C.props.onVnodeUpdated)&&fe(()=>Ee(B,T,C,A),h)}else{let C;const{el:w,props:O}=f,{bm:T,m:A,parent:H}=i,B=_t(f);if(ke(i,!1),T&&is(T),!B&&(C=O&&O.onVnodeBeforeMount)&&Ee(C,H,f),ke(i,!0),w&&os){const J=()=>{i.subTree=cs(i),os(w,i.subTree,i,h,null)};B?f.type.__asyncLoader().then(()=>!i.isUnmounted&&J()):J()}else{const J=i.subTree=cs(i);$(null,J,d,p,i,h,v),f.el=J.el}if(A&&fe(A,h),!B&&(C=O&&O.onVnodeMounted)){const J=f;fe(()=>Ee(C,H,J),h)}(f.shapeFlag&256||H&&_t(H.vnode)&&H.vnode.shapeFlag&256)&&i.a&&fe(i.a,h),i.isMounted=!0,f=d=p=null}},b=i.effect=new Ss(m,()=>Ks(_),i.scope),_=i.update=()=>b.run();_.id=i.uid,ke(i,!0),_()},z=(i,f,d)=>{f.component=i;const p=i.vnode.props;i.vnode=f,i.next=null,cl(i,f.props,p,d),al(i,f.children,d),ct(),un(),ft()},D=(i,f,d,p,h,v,y,m,b=!1)=>{const _=i&&i.children,C=i?i.shapeFlag:0,w=f.children,{patchFlag:O,shapeFlag:T}=f;if(O>0){if(O&128){It(_,w,d,p,h,v,y,m,b);return}else if(O&256){Le(_,w,d,p,h,v,y,m,b);return}}T&8?(C&16&&Pe(_,h,v),w!==_&&g(d,w)):C&16?T&16?It(_,w,d,p,h,v,y,m,b):Pe(_,h,v,!0):(C&8&&g(d,""),T&16&&De(w,d,p,h,v,y,m,b))},Le=(i,f,d,p,h,v,y,m,b)=>{i=i||Qe,f=f||Qe;const _=i.length,C=f.length,w=Math.min(_,C);let O;for(O=0;OC?Pe(i,h,v,!0,!1,w):De(f,d,p,h,v,y,m,b,w)},It=(i,f,d,p,h,v,y,m,b)=>{let _=0;const C=f.length;let w=i.length-1,O=C-1;for(;_<=w&&_<=O;){const T=i[_],A=f[_]=b?Re(f[_]):Oe(f[_]);if(ht(T,A))$(T,A,d,null,h,v,y,m,b);else break;_++}for(;_<=w&&_<=O;){const T=i[w],A=f[O]=b?Re(f[O]):Oe(f[O]);if(ht(T,A))$(T,A,d,null,h,v,y,m,b);else break;w--,O--}if(_>w){if(_<=O){const T=O+1,A=TO)for(;_<=w;)xe(i[_],h,v,!0),_++;else{const T=_,A=_,H=new Map;for(_=A;_<=O;_++){const de=f[_]=b?Re(f[_]):Oe(f[_]);de.key!=null&&H.set(de.key,_)}let B,J=0;const ge=O-A+1;let Ze=!1,Qs=0;const dt=new Array(ge);for(_=0;_=ge){xe(de,h,v,!0);continue}let we;if(de.key!=null)we=H.get(de.key);else for(B=A;B<=O;B++)if(dt[B-A]===0&&ht(de,f[B])){we=B;break}we===void 0?xe(de,h,v,!0):(dt[we-A]=_+1,we>=Qs?Qs=we:Ze=!0,$(de,f[we],d,null,h,v,y,m,b),J++)}const Gs=Ze?pl(dt):Qe;for(B=Gs.length-1,_=ge-1;_>=0;_--){const de=A+_,we=f[de],en=de+1{const{el:v,type:y,transition:m,children:b,shapeFlag:_}=i;if(_&6){Ue(i.component.subTree,f,d,p);return}if(_&128){i.suspense.move(f,d,p);return}if(_&64){y.move(i,f,d,Je);return}if(y===he){r(v,f,d);for(let w=0;wm.enter(v),h);else{const{leave:w,delayLeave:O,afterLeave:T}=m,A=()=>r(v,f,d),H=()=>{w(v,()=>{A(),T&&T()})};O?O(v,A,H):H()}else r(v,f,d)},xe=(i,f,d,p=!1,h=!1)=>{const{type:v,props:y,ref:m,children:b,dynamicChildren:_,shapeFlag:C,patchFlag:w,dirs:O}=i;if(m!=null&&Os(m,null,d,i,!0),C&256){f.ctx.deactivate(i);return}const T=C&1&&O,A=!_t(i);let H;if(A&&(H=y&&y.onVnodeBeforeUnmount)&&Ee(H,f,i),C&6)Mr(i.component,d,p);else{if(C&128){i.suspense.unmount(d,p);return}T&&Ke(i,null,f,"beforeUnmount"),C&64?i.type.remove(i,f,d,h,Je,p):_&&(v!==he||w>0&&w&64)?Pe(_,f,d,!1,!0):(v===he&&w&384||!h&&C&16)&&Pe(b,f,d),p&&Vs(i)}(A&&(H=y&&y.onVnodeUnmounted)||T)&&fe(()=>{H&&Ee(H,f,i),T&&Ke(i,null,f,"unmounted")},d)},Vs=i=>{const{type:f,el:d,anchor:p,transition:h}=i;if(f===he){Ir(d,p);return}if(f===as){F(i);return}const v=()=>{n(d),h&&!h.persisted&&h.afterLeave&&h.afterLeave()};if(i.shapeFlag&1&&h&&!h.persisted){const{leave:y,delayLeave:m}=h,b=()=>y(d,v);m?m(i.el,v,b):b()}else v()},Ir=(i,f)=>{let d;for(;i!==f;)d=E(i),n(i),i=d;n(f)},Mr=(i,f,d)=>{const{bum:p,scope:h,update:v,subTree:y,um:m}=i;p&&is(p),h.stop(),v&&(v.active=!1,xe(y,i,f,d)),m&&fe(m,f),fe(()=>{i.isUnmounted=!0},f),f&&f.pendingBranch&&!f.isUnmounted&&i.asyncDep&&!i.asyncResolved&&i.suspenseId===f.pendingId&&(f.deps--,f.deps===0&&f.resolve())},Pe=(i,f,d,p=!1,h=!1,v=0)=>{for(let y=v;yi.shapeFlag&6?Mt(i.component.subTree):i.shapeFlag&128?i.suspense.next():E(i.anchor||i.el),Xs=(i,f,d)=>{i==null?f._vnode&&xe(f._vnode,null,null,!0):$(f._vnode||null,i,f,null,null,null,d),un(),nr(),f._vnode=i},Je={p:$,um:xe,m:Ue,r:Vs,mt:ns,mc:De,pc:D,pbc:He,n:Mt,o:e};let rs,os;return t&&([rs,os]=t(Je)),{render:Xs,hydrate:rs,createApp:ol(Xs,rs)}}function ke({effect:e,update:t},s){e.allowRecurse=t.allowRecurse=s}function wr(e,t,s=!1){const r=e.children,n=t.children;if(P(r)&&P(n))for(let o=0;o>1,e[s[c]]0&&(t[r]=s[o-1]),s[o]=r)}}for(o=s.length,l=s[o-1];o-- >0;)s[o]=l,l=t[l];return s}const gl=e=>e.__isTeleport,he=Symbol.for("v-fgt"),es=Symbol.for("v-txt"),Be=Symbol.for("v-cmt"),as=Symbol.for("v-stc"),vt=[];let ve=null;function R(e=!1){vt.push(ve=e?null:[])}function _l(){vt.pop(),ve=vt[vt.length-1]||null}let Et=1;function yn(e){Et+=e}function Er(e){return e.dynamicChildren=Et>0?ve||Qe:null,_l(),Et>0&&ve&&ve.push(e),e}function q(e,t,s,r,n,o){return Er(ee(e,t,s,r,n,o,!0))}function pe(e,t,s,r,n){return Er(L(e,t,s,r,n,!0))}function Cr(e){return e?e.__v_isVNode===!0:!1}function ht(e,t){return e.type===t.type&&e.key===t.key}const ts="__vInternal",Or=({key:e})=>e??null,Ht=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?V(e)||le(e)||M(e)?{i:ue,r:e,k:t,f:!!s}:e:null);function ee(e,t=null,s=null,r=0,n=null,o=e===he?0:1,l=!1,c=!1){const u={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Or(t),ref:t&&Ht(t),scopeId:lr,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:r,dynamicProps:n,dynamicChildren:null,appContext:null,ctx:ue};return c?(zs(u,s),o&128&&e.normalize(u)):s&&(u.shapeFlag|=V(s)?8:16),Et>0&&!l&&ve&&(u.patchFlag>0||o&6)&&u.patchFlag!==32&&ve.push(u),u}const L=ml;function ml(e,t=null,s=null,r=0,n=null,o=!1){if((!e||e===Vo)&&(e=Be),Cr(e)){const c=rt(e,t,!0);return s&&zs(c,s),Et>0&&!o&&ve&&(c.shapeFlag&6?ve[ve.indexOf(e)]=c:ve.push(c)),c.patchFlag|=-2,c}if(Pl(e)&&(e=e.__vccOpts),t){t=vl(t);let{class:c,style:u}=t;c&&!V(c)&&(t.class=it(c)),W(u)&&(Vn(u)&&!P(u)&&(u=G({},u)),t.style=Jt(u))}const l=V(e)?1:No(e)?128:gl(e)?64:W(e)?4:M(e)?2:0;return ee(e,t,s,r,n,l,o,!0)}function vl(e){return e?Vn(e)||ts in e?G({},e):e:null}function rt(e,t,s=!1){const{props:r,ref:n,patchFlag:o,children:l}=e,c=t?bl(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:c,key:c&&Or(c),ref:t&&t.ref?s&&n?P(n)?n.concat(Ht(t)):[n,Ht(t)]:Ht(t):n,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==he?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&rt(e.ssContent),ssFallback:e.ssFallback&&rt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function j(e=" ",t=0){return L(es,null,e,t)}function Z(e="",t=!1){return t?(R(),pe(Be,null,e)):L(Be,null,e)}function Oe(e){return e==null||typeof e=="boolean"?L(Be):P(e)?L(he,null,e.slice()):typeof e=="object"?Re(e):L(es,null,String(e))}function Re(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:rt(e)}function zs(e,t){let s=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(P(t))s=16;else if(typeof t=="object")if(r&65){const n=t.default;n&&(n._c&&(n._d=!1),zs(e,n()),n._c&&(n._d=!0));return}else{s=32;const n=t._;!n&&!(ts in t)?t._ctx=ue:n===3&&ue&&(ue.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else M(t)?(t={default:t,_ctx:ue},s=32):(t=String(t),r&64?(s=16,t=[j(t)]):s=8);e.children=t,e.shapeFlag|=s}function bl(...e){const t={};for(let s=0;soe=e),qs=e=>{Ve.length>1?Ve.forEach(t=>t(e)):Ve[0](e)};const ot=e=>{qs(e),e.scope.on()},Ye=()=>{oe&&oe.scope.off(),qs(null)};function Tr(e){return e.vnode.shapeFlag&4}let Ct=!1;function El(e,t=!1){Ct=t;const{props:s,children:r}=e.vnode,n=Tr(e);il(e,s,n,t),ul(e,r);const o=n?Cl(e,t):void 0;return Ct=!1,o}function Cl(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=Xn(new Proxy(e.ctx,Qo));const{setup:r}=s;if(r){const n=e.setupContext=r.length>1?Tl(e):null;ot(e),ct();const o=je(r,e,0,[e.props,n]);if(ft(),Ye(),Rn(o)){if(o.then(Ye,Ye),t)return o.then(l=>{wn(e,l,t)}).catch(l=>{Vt(l,e,0)});e.asyncDep=o}else wn(e,o,t)}else Pr(e,t)}function wn(e,t,s){M(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:W(t)&&(e.setupState=er(t)),Pr(e,s)}let En;function Pr(e,t,s){const r=e.type;if(!e.render){if(!t&&En&&!r.render){const n=r.template||ks(e).template;if(n){const{isCustomElement:o,compilerOptions:l}=e.appContext.config,{delimiters:c,compilerOptions:u}=r,a=G(G({isCustomElement:o,delimiters:c},l),u);r.render=En(n,a)}}e.render=r.render||be}ot(e),ct(),Go(e),ft(),Ye()}function Ol(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,s){return ae(e,"get","$attrs"),t[s]}}))}function Tl(e){const t=s=>{e.exposed=s||{}};return{get attrs(){return Ol(e)},slots:e.slots,emit:e.emit,expose:t}}function Ys(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(er(Xn(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in mt)return mt[s](e)},has(t,s){return s in t||s in mt}}))}function Pl(e){return M(e)&&"__vccOpts"in e}const Ts=(e,t)=>Co(e,t,Ct),Il=Symbol.for("v-scx"),Ml=()=>Dt(Il),Fl="3.3.4",Al="http://www.w3.org/2000/svg",ze=typeof document<"u"?document:null,Cn=ze&&ze.createElement("template"),$l={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,r)=>{const n=t?ze.createElementNS(Al,e):ze.createElement(e,s?{is:s}:void 0);return e==="select"&&r&&r.multiple!=null&&n.setAttribute("multiple",r.multiple),n},createText:e=>ze.createTextNode(e),createComment:e=>ze.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>ze.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,r,n,o){const l=s?s.previousSibling:t.lastChild;if(n&&(n===o||n.nextSibling))for(;t.insertBefore(n.cloneNode(!0),s),!(n===o||!(n=n.nextSibling)););else{Cn.innerHTML=r?`${e}`:e;const c=Cn.content;if(r){const u=c.firstChild;for(;u.firstChild;)c.appendChild(u.firstChild);c.removeChild(u)}t.insertBefore(c,s)}return[l?l.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}};function Rl(e,t,s){const r=e._vtc;r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}function Sl(e,t,s){const r=e.style,n=V(s);if(s&&!n){if(t&&!V(t))for(const o in t)s[o]==null&&Ps(r,o,"");for(const o in s)Ps(r,o,s[o])}else{const o=r.display;n?t!==s&&(r.cssText=s):t&&e.removeAttribute("style"),"_vod"in e&&(r.display=o)}}const On=/\s*!important$/;function Ps(e,t,s){if(P(s))s.forEach(r=>Ps(e,t,r));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const r=jl(e,t);On.test(s)?e.setProperty(lt(r),s.replace(On,""),"important"):e[r]=s}}const Tn=["Webkit","Moz","ms"],ds={};function jl(e,t){const s=ds[t];if(s)return s;let r=st(t);if(r!=="filter"&&r in e)return ds[t]=r;r=Nn(r);for(let n=0;nhs||(Kl.then(()=>hs=0),hs=Date.now());function Wl(e,t){const s=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=s.attached)return;ye(zl(r,s.value),t,5,[r])};return s.value=e,s.attached=kl(),s}function zl(e,t){if(P(t)){const s=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{s.call(e),e._stopped=!0},t.map(r=>n=>!n._stopped&&r&&r(n))}else return t}const Mn=/^on[a-z]/,ql=(e,t,s,r,n=!1,o,l,c,u)=>{t==="class"?Rl(e,r,n):t==="style"?Sl(e,s,r):zt(t)?Ms(t)||Ll(e,t,s,r,l):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Yl(e,t,r,n))?Bl(e,t,r,o,l,c,u):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Nl(e,t,r,n))};function Yl(e,t,s,r){return r?!!(t==="innerHTML"||t==="textContent"||t in e&&Mn.test(t)&&M(s)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||Mn.test(t)&&V(s)?!1:t in e}const Jl=G({patchProp:ql},$l);let Fn;function Zl(){return Fn||(Fn=dl(Jl))}const Vl=(...e)=>{const t=Zl().createApp(...e),{mount:s}=t;return t.mount=r=>{const n=Xl(r);if(!n)return;const o=t._component;!M(o)&&!o.render&&!o.template&&(o.template=n.innerHTML),n.innerHTML="";const l=s(n,!1,n instanceof SVGElement);return n instanceof Element&&(n.removeAttribute("v-cloak"),n.setAttribute("data-v-app","")),l},t};function Xl(e){return V(e)?document.querySelector(e):e}const Js=(e,t)=>{const s=e.__vccOpts||e;for(const[r,n]of t)s[r]=n;return s},Ql={},Gl={xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},ei=ee("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18"},null,-1),ti=[ei];function si(e,t){return R(),q("svg",Gl,ti)}const ni=Js(Ql,[["render",si]]),ri={},oi={xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},li=ee("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3"},null,-1),ii=[li];function ci(e,t){return R(),q("svg",oi,ii)}const fi=Js(ri,[["render",ci]]),ui={class:"inline-block text-sm bg-gray-200 rounded-full overflow-hidden relative"},ai=Qt({__name:"Progress",props:{value:{},max:{}},setup(e){return(t,s)=>(R(),q("div",ui,[ee("div",{class:it(["px-2 text-sm transition-[width] duration-500 whitespace-nowrap",{"bg-gray-400/50":t.value/t.max<.8,"bg-orange-300":t.value/t.max>=.8&&t.value/t.max<.9,"bg-red-300":t.value/t.max>=.9}]),style:Jt({width:`${t.value/t.max*100}%`})},[hr(t.$slots,"default")],6)]))}}),di={},hi={class:"inline-block bg-gray-200 px-2 rounded-full text-sm"};function pi(e,t){return R(),q("div",hi,[hr(e.$slots,"default")])}const gi=Js(di,[["render",pi]]),_i=Qt({__name:"StatusIndicator",props:{status:{type:Boolean}},setup(e){return(t,s)=>(R(),q("div",{class:it(["rounded-full inline-block",{"bg-green-400":t.status,"bg-red-500":!t.status}])},null,2))}});function Ce(e,t=2){if(e===0)return"0 B";const s=1024,r=t<0?0:t,n=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],o=Math.floor(Math.log(e)/Math.log(s));return`${Number.parseFloat((e/s**o).toFixed(r))} ${n[o]}`}function mi(e){const t=new Date(e*1e3),s=t.getFullYear(),r=(t.getMonth()+1).toString().padStart(2,"0"),n=t.getDate().toString().padStart(2,"0"),o=t.getHours().toString().padStart(2,"0"),l=t.getMinutes().toString().padStart(2,"0"),c=t.getSeconds().toString().padStart(2,"0");return`${s}/${r}/${n} ${o}:${l}:${c}`}function ps(e){return e.online4||e.online6}function vi(e){return/[\uD800-\uDBFF][\uDC00-\uDFFF]/g.test(e)}const bi={class:"rounded-xl px-4 py-3 transition-all relative bg-gray-100 border border-transparent hover:border-gray-400 hover:shadow-md hover:bg-white duration-300"},yi={class:"absolute right-4 top-4 group flex flex-col items-end"},xi={class:"hidden group-hover:block p-2 rounded-xl border text-sm bg-white z-[9999] mt-1 border-gray-400"},wi={class:"flex gap-2"},Ei={class:"flex items-center gap-1"},Ci={class:"flex items-center gap-1"},Oi={key:0},Ti=ee("br",null,null,-1),Pi={class:"text-lg flex items-center gap-2"},Ii={key:0},Mi=["src","alt"],Fi=["src","alt"],Ai={class:"flex items-center gap-2"},$i={key:0,class:"flex items-center gap-2"},Ri={key:1,class:"flex items-center gap-2"},Si={key:2,class:"flex items-center gap-2"},ji={key:3,class:"flex items-center gap-2"},Ni={key:4,class:"flex items-center gap-2"},Bi={key:5},Di={class:"flex gap-1 flex-wrap mt-1"},Hi=Qt({__name:"ServerItem",props:{server:{}},setup(e){const t=e,s=Ts(()=>{if(!t.server.labels)return{};const n=t.server.labels.split(";"),o={};return n.forEach(l=>{if(l==="")return;const[c,u]=l.split("=");o[c]=u}),o}),r=Ts(()=>!t.server.load&&!t.server.load_1&&!t.server.load_5&&!t.server.load_15);return(n,o)=>{const l=_i,c=gi,u=ai,a=fi,g=ni;return R(),q("div",bi,[ee("div",yi,[L(l,{status:U(ps)(n.server),class:"w-3 h-3"},null,8,["status"]),ee("div",xi,[ee("div",wi,[ee("div",Ei,[j(" IPv4 "),L(l,{status:n.server.online4,class:"w-2 h-2"},null,8,["status"])]),ee("div",Ci,[j(" IPv6 "),L(l,{status:n.server.online6,class:"w-2 h-2"},null,8,["status"])])]),n.server.latest_ts?(R(),q("div",Oi,[j(" 最后上报时间"),Ti,j(" "+k(U(mi)(n.server.latest_ts)),1)])):Z("",!0)])]),ee("div",Pi,[U(vi)(n.server.location)?(R(),q("span",Ii,k(n.server.location),1)):(R(),q("img",{key:1,src:`/image/flags/${n.server.location.toLowerCase()}.svg`,alt:`${n.server.location} flag`,class:"h-4 inline-block rounded-sm"},null,8,Mi)),U(s).os?(R(),q("img",{key:2,src:`/image/os/${U(s).os}.svg`,alt:`${U(s).os} os`,class:"h-4 inline-block rounded-sm"},null,8,Fi)):Z("",!0),j(" "+k(n.server.alias||n.server.name),1)]),ee("div",null,[j(" 运行时间 "),ee("span",{class:it({"text-red-500":!U(ps)(n.server)})},k(U(ps)(n.server)?n.server.uptime:"离线"),3)]),ee("div",Ai,[j(" 负载 "),U(r)?(R(),pe(c,{key:0},{default:Q(()=>[j(" 无数据 ")]),_:1})):Z("",!0),n.server.load?(R(),pe(c,{key:1},{default:Q(()=>[j(k(n.server.load),1)]),_:1})):Z("",!0),n.server.load_1?(R(),pe(c,{key:2},{default:Q(()=>[j(k(n.server.load_1),1)]),_:1})):Z("",!0),n.server.load_5?(R(),pe(c,{key:3},{default:Q(()=>[j(k(n.server.load_5),1)]),_:1})):Z("",!0),n.server.load_15?(R(),pe(c,{key:4},{default:Q(()=>[j(k(n.server.load_15),1)]),_:1})):Z("",!0)]),n.server.cpu?(R(),q("div",$i,[j(" CPU "),L(u,{value:n.server.cpu,max:100,text:`${n.server.cpu}%`,class:"flex-1"},{default:Q(()=>[j(k(n.server.cpu)+"% ",1)]),_:1},8,["value","text"])])):Z("",!0),n.server.memory_total?(R(),q("div",Ri,[j(" 内存 "),L(u,{value:n.server.memory_used,max:n.server.memory_total,class:"flex-1"},{default:Q(()=>[j(k(U(Ce)(n.server.memory_used*1024))+" / "+k(U(Ce)(n.server.memory_total*1024)),1)]),_:1},8,["value","max"])])):Z("",!0),n.server.hdd_total?(R(),q("div",Si,[j(" 硬盘 "),L(u,{value:n.server.hdd_used,max:n.server.hdd_total,class:"flex-1"},{default:Q(()=>[j(k(U(Ce)(n.server.hdd_used*1024*1024))+" / "+k(U(Ce)(n.server.hdd_total*1024*1024)),1)]),_:1},8,["value","max"])])):Z("",!0),n.server.network_rx?(R(),q("div",ji,[j(" 网络 "),L(c,{class:"flex items-center"},{default:Q(()=>[L(a,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_rx,1))+"/s ",1)]),_:1}),L(c,{class:"flex items-center"},{default:Q(()=>[L(g,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_tx,1))+"/s ",1)]),_:1})])):Z("",!0),n.server.network_in?(R(),q("div",Ni,[j(" 流量 "),L(c,{class:"flex items-center"},{default:Q(()=>[L(a,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_in,1)),1)]),_:1}),L(c,{class:"flex items-center"},{default:Q(()=>[L(g,{class:"w-4 h-4"}),j(k(U(Ce)(n.server.network_out,1)),1)]),_:1})])):Z("",!0),n.server.swap_total?(R(),q("div",Bi,[j(" SWAP "),L(c,null,{default:Q(()=>[j(k(U(Ce)(n.server.swap_used*1024))+" / "+k(U(Ce)(n.server.swap_total*1024)),1)]),_:1})])):Z("",!0),ee("div",Di,[n.server.tcp_count?(R(),pe(c,{key:0},{default:Q(()=>[j(" TCP "+k(n.server.tcp_count),1)]),_:1})):Z("",!0),n.server.udp_count?(R(),pe(c,{key:1},{default:Q(()=>[j(" UDP "+k(n.server.udp_count),1)]),_:1})):Z("",!0),n.server.process_count?(R(),pe(c,{key:2},{default:Q(()=>[j(" 进程 "+k(n.server.process_count),1)]),_:1})):Z("",!0),n.server.thread_count?(R(),pe(c,{key:3},{default:Q(()=>[j(" 线程 "+k(n.server.thread_count),1)]),_:1})):Z("",!0)])])}}}),Li={key:0,class:"w-fit mx-auto my-2"},Ui={key:1,class:"w-fit mx-auto my-2"},Ki={key:2,class:"flex flex-wrap gap-x-4 gap-y-3"},ki=ee("div",{class:"h-16"},null,-1),An="/json/stats.json",Wi=Qt({__name:"App",setup(e){const t=jt(),s=jt(!0),r=jt(!1),n=jt(!1);ar(()=>{fetch(An).then(l=>l.json()).then(l=>{t.value=l,setInterval(()=>{o()},500)}).catch(()=>{r.value=!0}).finally(()=>{s.value=!1})});function o(){n.value||(n.value=!0,fetch(An).then(l=>l.json()).then(l=>{t.value=l,r.value=!1}).catch(()=>{r.value=!0}).finally(()=>{n.value=!1}))}return(l,c)=>{const u=Hi;return R(),q(he,null,[U(s)?(R(),q("div",Li," 加载中 ")):Z("",!0),U(r)?(R(),q("div",Ui," 数据加载失败,请尝试刷新页面或检查 ServerStatus 服务端状态 ")):Z("",!0),U(t)?(R(),q("div",Ki,[(R(!0),q(he,null,Xo(U(t).servers,(a,g)=>(R(),pe(u,{key:g,server:a,class:"flex-1 min-w-[300px]"},null,8,["server"]))),128))])):Z("",!0),ki],64)}}});const zi=Vl(Wi);zi.mount("#app"); diff --git a/web/assets/index-e069a4f0.js b/web/assets/index-e069a4f0.js new file mode 100644 index 00000000..e46b9844 --- /dev/null +++ b/web/assets/index-e069a4f0.js @@ -0,0 +1 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&s(l)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();function Pn(e,t){const n=Object.create(null),s=e.split(",");for(let r=0;r!!n[r.toLowerCase()]:r=>!!n[r]}const L={},Ve=[],me=()=>{},Fr=()=>!1,Ar=/^on[^a-z]/,Wt=e=>Ar.test(e),In=e=>e.startsWith("onUpdate:"),X=Object.assign,Mn=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},$r=Object.prototype.hasOwnProperty,R=(e,t)=>$r.call(e,t),P=Array.isArray,Xe=e=>zt(e)==="[object Map]",As=e=>zt(e)==="[object Set]",M=e=>typeof e=="function",J=e=>typeof e=="string",Fn=e=>typeof e=="symbol",W=e=>e!==null&&typeof e=="object",$s=e=>W(e)&&M(e.then)&&M(e.catch),Rs=Object.prototype.toString,zt=e=>Rs.call(e),Rr=e=>zt(e).slice(8,-1),Ss=e=>zt(e)==="[object Object]",An=e=>J(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,jt=Pn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),kt=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Sr=/-(\w)/g,et=kt(e=>e.replace(Sr,(t,n)=>n?n.toUpperCase():"")),jr=/\B([A-Z])/g,rt=kt(e=>e.replace(jr,"-$1").toLowerCase()),js=kt(e=>e.charAt(0).toUpperCase()+e.slice(1)),rn=kt(e=>e?`on${js(e)}`:""),bt=(e,t)=>!Object.is(e,t),on=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Nr=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let ts;const gn=()=>ts||(ts=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function qt(e){if(P(e)){const t={};for(let n=0;n{if(n){const s=n.split(Dr);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function ot(e){let t="";if(J(e))t=e;else if(P(e))for(let n=0;nJ(e)?e:e==null?"":P(e)||W(e)&&(e.toString===Rs||!M(e.toString))?JSON.stringify(e,Bs,2):String(e),Bs=(e,t)=>t&&t.__v_isRef?Bs(e,t.value):Xe(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r])=>(n[`${s} =>`]=r,n),{})}:As(t)?{[`Set(${t.size})`]:[...t.values()]}:W(t)&&!P(t)&&!Ss(t)?String(t):t;let pe;class Wr{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=pe,!t&&pe&&(this.index=(pe.scopes||(pe.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=pe;try{return pe=this,t()}finally{pe=n}}}on(){pe=this}off(){pe=this.parent}stop(t){if(this._active){let n,s;for(n=0,s=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},Ds=e=>(e.w&Se)>0,Hs=e=>(e.n&Se)>0,qr=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let s=0;s{(_==="length"||_>=u)&&c.push(a)})}else switch(n!==void 0&&c.push(l.get(n)),t){case"add":P(e)?An(n)&&c.push(l.get("length")):(c.push(l.get(ze)),Xe(e)&&c.push(l.get(bn)));break;case"delete":P(e)||(c.push(l.get(ze)),Xe(e)&&c.push(l.get(bn)));break;case"set":Xe(e)&&c.push(l.get(ze));break}if(c.length===1)c[0]&&vn(c[0]);else{const u=[];for(const a of c)a&&u.push(...a);vn($n(u))}}function vn(e,t){const n=P(e)?e:[...e];for(const s of n)s.computed&&ss(s);for(const s of n)s.computed||ss(s)}function ss(e,t){(e!==ge||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}const Jr=Pn("__proto__,__v_isRef,__isVue"),Ks=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Fn)),Zr=Sn(),Vr=Sn(!1,!0),Xr=Sn(!0),rs=Qr();function Qr(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const s=j(this);for(let o=0,l=this.length;o{e[t]=function(...n){lt();const s=j(this)[t].apply(this,n);return it(),s}}),e}function Gr(e){const t=j(this);return ue(t,"has",e),t.hasOwnProperty(e)}function Sn(e=!1,t=!1){return function(s,r,o){if(r==="__v_isReactive")return!e;if(r==="__v_isReadonly")return e;if(r==="__v_isShallow")return t;if(r==="__v_raw"&&o===(e?t?_o:Ys:t?qs:ks).get(s))return s;const l=P(s);if(!e){if(l&&R(rs,r))return Reflect.get(rs,r,o);if(r==="hasOwnProperty")return Gr}const c=Reflect.get(s,r,o);return(Fn(r)?Ks.has(r):Jr(r))||(e||ue(s,"get",r),t)?c:re(c)?l&&An(r)?c:c.value:W(c)?e?Js(c):Bn(c):c}}const eo=Ws(),to=Ws(!0);function Ws(e=!1){return function(n,s,r,o){let l=n[s];if(tt(l)&&re(l)&&!re(r))return!1;if(!e&&(!Ht(r)&&!tt(r)&&(l=j(l),r=j(r)),!P(n)&&re(l)&&!re(r)))return l.value=r,!0;const c=P(n)&&An(s)?Number(s)e,Yt=e=>Reflect.getPrototypeOf(e);function Mt(e,t,n=!1,s=!1){e=e.__v_raw;const r=j(e),o=j(t);n||(t!==o&&ue(r,"get",t),ue(r,"get",o));const{has:l}=Yt(r),c=s?jn:n?Hn:vt;if(l.call(r,t))return c(e.get(t));if(l.call(r,o))return c(e.get(o));e!==r&&e.get(t)}function Ft(e,t=!1){const n=this.__v_raw,s=j(n),r=j(e);return t||(e!==r&&ue(s,"has",e),ue(s,"has",r)),e===r?n.has(e):n.has(e)||n.has(r)}function At(e,t=!1){return e=e.__v_raw,!t&&ue(j(e),"iterate",ze),Reflect.get(e,"size",e)}function os(e){e=j(e);const t=j(this);return Yt(t).has.call(t,e)||(t.add(e),Pe(t,"add",e,e)),this}function ls(e,t){t=j(t);const n=j(this),{has:s,get:r}=Yt(n);let o=s.call(n,e);o||(e=j(e),o=s.call(n,e));const l=r.call(n,e);return n.set(e,t),o?bt(t,l)&&Pe(n,"set",e,t):Pe(n,"add",e,t),this}function is(e){const t=j(this),{has:n,get:s}=Yt(t);let r=n.call(t,e);r||(e=j(e),r=n.call(t,e)),s&&s.call(t,e);const o=t.delete(e);return r&&Pe(t,"delete",e,void 0),o}function cs(){const e=j(this),t=e.size!==0,n=e.clear();return t&&Pe(e,"clear",void 0,void 0),n}function $t(e,t){return function(s,r){const o=this,l=o.__v_raw,c=j(l),u=t?jn:e?Hn:vt;return!e&&ue(c,"iterate",ze),l.forEach((a,_)=>s.call(r,u(a),u(_),o))}}function Rt(e,t,n){return function(...s){const r=this.__v_raw,o=j(r),l=Xe(o),c=e==="entries"||e===Symbol.iterator&&l,u=e==="keys"&&l,a=r[e](...s),_=n?jn:t?Hn:vt;return!t&&ue(o,"iterate",u?bn:ze),{next(){const{value:y,done:E}=a.next();return E?{value:y,done:E}:{value:c?[_(y[0]),_(y[1])]:_(y),done:E}},[Symbol.iterator](){return this}}}}function Fe(e){return function(...t){return e==="delete"?!1:this}}function io(){const e={get(o){return Mt(this,o)},get size(){return At(this)},has:Ft,add:os,set:ls,delete:is,clear:cs,forEach:$t(!1,!1)},t={get(o){return Mt(this,o,!1,!0)},get size(){return At(this)},has:Ft,add:os,set:ls,delete:is,clear:cs,forEach:$t(!1,!0)},n={get(o){return Mt(this,o,!0)},get size(){return At(this,!0)},has(o){return Ft.call(this,o,!0)},add:Fe("add"),set:Fe("set"),delete:Fe("delete"),clear:Fe("clear"),forEach:$t(!0,!1)},s={get(o){return Mt(this,o,!0,!0)},get size(){return At(this,!0)},has(o){return Ft.call(this,o,!0)},add:Fe("add"),set:Fe("set"),delete:Fe("delete"),clear:Fe("clear"),forEach:$t(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=Rt(o,!1,!1),n[o]=Rt(o,!0,!1),t[o]=Rt(o,!1,!0),s[o]=Rt(o,!0,!0)}),[e,n,t,s]}const[co,fo,uo,ao]=io();function Nn(e,t){const n=t?e?ao:uo:e?fo:co;return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(R(n,r)&&r in s?n:s,r,o)}const ho={get:Nn(!1,!1)},po={get:Nn(!1,!0)},go={get:Nn(!0,!1)},ks=new WeakMap,qs=new WeakMap,Ys=new WeakMap,_o=new WeakMap;function mo(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function bo(e){return e.__v_skip||!Object.isExtensible(e)?0:mo(Rr(e))}function Bn(e){return tt(e)?e:Dn(e,!1,zs,ho,ks)}function vo(e){return Dn(e,!1,lo,po,qs)}function Js(e){return Dn(e,!0,oo,go,Ys)}function Dn(e,t,n,s,r){if(!W(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=r.get(e);if(o)return o;const l=bo(e);if(l===0)return e;const c=new Proxy(e,l===2?s:n);return r.set(e,c),c}function Qe(e){return tt(e)?Qe(e.__v_raw):!!(e&&e.__v_isReactive)}function tt(e){return!!(e&&e.__v_isReadonly)}function Ht(e){return!!(e&&e.__v_isShallow)}function Zs(e){return Qe(e)||tt(e)}function j(e){const t=e&&e.__v_raw;return t?j(t):e}function Vs(e){return Dt(e,"__v_skip",!0),e}const vt=e=>W(e)?Bn(e):e,Hn=e=>W(e)?Js(e):e;function Xs(e){$e&&ge&&(e=j(e),Us(e.dep||(e.dep=$n())))}function Qs(e,t){e=j(e);const n=e.dep;n&&vn(n)}function re(e){return!!(e&&e.__v_isRef===!0)}function ln(e){return xo(e,!1)}function xo(e,t){return re(e)?e:new yo(e,t)}class yo{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:j(t),this._value=n?t:vt(t)}get value(){return Xs(this),this._value}set value(t){const n=this.__v_isShallow||Ht(t)||tt(t);t=n?t:j(t),bt(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:vt(t),Qs(this))}}function U(e){return re(e)?e.value:e}const wo={get:(e,t,n)=>U(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return re(r)&&!re(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Gs(e){return Qe(e)?e:new Proxy(e,wo)}class Eo{constructor(t,n,s,r){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new Rn(t,()=>{this._dirty||(this._dirty=!0,Qs(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!r,this.__v_isReadonly=s}get value(){const t=j(this);return Xs(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function Co(e,t,n=!1){let s,r;const o=M(e);return o?(s=e,r=me):(s=e.get,r=e.set),new Eo(s,r,o||!r,n)}function Re(e,t,n,s){let r;try{r=s?e(...s):e()}catch(o){Jt(o,t,n)}return r}function be(e,t,n,s){if(M(e)){const o=Re(e,t,n,s);return o&&$s(o)&&o.catch(l=>{Jt(l,t,n)}),o}const r=[];for(let o=0;o>>1;yt(ne[s])Ce&&ne.splice(t,1)}function Mo(e){P(e)?Ge.push(...e):(!Te||!Te.includes(e,e.allowRecurse?Ke+1:Ke))&&Ge.push(e),tr()}function fs(e,t=xt?Ce+1:0){for(;tyt(n)-yt(s)),Ke=0;Kee.id==null?1/0:e.id,Fo=(e,t)=>{const n=yt(e)-yt(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function sr(e){xn=!1,xt=!0,ne.sort(Fo);const t=me;try{for(Ce=0;CeJ(I)?I.trim():I)),y&&(r=n.map(Nr))}let c,u=s[c=rn(t)]||s[c=rn(et(t))];!u&&o&&(u=s[c=rn(rt(t))]),u&&be(u,e,6,r);const a=s[c+"Once"];if(a){if(!e.emitted)e.emitted={};else if(e.emitted[c])return;e.emitted[c]=!0,be(a,e,6,r)}}function rr(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let l={},c=!1;if(!M(e)){const u=a=>{const _=rr(a,t,!0);_&&(c=!0,X(l,_))};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}return!o&&!c?(W(e)&&s.set(e,null),null):(P(o)?o.forEach(u=>l[u]=null):X(l,o),W(e)&&s.set(e,l),l)}function Zt(e,t){return!e||!Wt(t)?!1:(t=t.slice(2).replace(/Once$/,""),R(e,t[0].toLowerCase()+t.slice(1))||R(e,rt(t))||R(e,t))}let fe=null,or=null;function Lt(e){const t=fe;return fe=e,or=e&&e.type.__scopeId||null,t}function te(e,t=fe,n){if(!t||e._n)return e;const s=(...r)=>{s._d&&vs(-1);const o=Lt(t);let l;try{l=e(...r)}finally{Lt(o),s._d&&vs(1)}return l};return s._n=!0,s._c=!0,s._d=!0,s}function cn(e){const{type:t,vnode:n,proxy:s,withProxy:r,props:o,propsOptions:[l],slots:c,attrs:u,emit:a,render:_,renderCache:y,data:E,setupState:I,ctx:q,inheritAttrs:$}=e;let Z,Q;const G=Lt(e);try{if(n.shapeFlag&4){const F=r||s;Z=Ee(_.call(F,F,y,o,I,E,q)),Q=u}else{const F=t;Z=Ee(F.length>1?F(o,{attrs:u,slots:c,emit:a}):F(o,null)),Q=t.props?u:$o(u)}}catch(F){_t.length=0,Jt(F,e,1),Z=S(je)}let ee=Z;if(Q&&$!==!1){const F=Object.keys(Q),{shapeFlag:Me}=ee;F.length&&Me&7&&(l&&F.some(In)&&(Q=Ro(Q,l)),ee=nt(ee,Q))}return n.dirs&&(ee=nt(ee),ee.dirs=ee.dirs?ee.dirs.concat(n.dirs):n.dirs),n.transition&&(ee.transition=n.transition),Z=ee,Lt(G),Z}const $o=e=>{let t;for(const n in e)(n==="class"||n==="style"||Wt(n))&&((t||(t={}))[n]=e[n]);return t},Ro=(e,t)=>{const n={};for(const s in e)(!In(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function So(e,t,n){const{props:s,children:r,component:o}=e,{props:l,children:c,patchFlag:u}=t,a=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&u>=0){if(u&1024)return!0;if(u&16)return s?us(s,l,a):!!l;if(u&8){const _=t.dynamicProps;for(let y=0;y<_.length;y++){const E=_[y];if(l[E]!==s[E]&&!Zt(a,E))return!0}}}else return(r||c)&&(!c||!c.$stable)?!0:s===l?!1:s?l?us(s,l,a):!0:!!l;return!1}function us(e,t,n){const s=Object.keys(t);if(s.length!==Object.keys(e).length)return!0;for(let r=0;re.__isSuspense;function Bo(e,t){t&&t.pendingBranch?P(e)?t.effects.push(...e):t.effects.push(e):Mo(e)}const St={};function fn(e,t,n){return lr(e,t,n)}function lr(e,t,{immediate:n,deep:s,flush:r,onTrack:o,onTrigger:l}=L){var c;const u=kr()===((c=se)==null?void 0:c.scope)?se:null;let a,_=!1,y=!1;if(re(e)?(a=()=>e.value,_=Ht(e)):Qe(e)?(a=()=>e,s=!0):P(e)?(y=!0,_=e.some(F=>Qe(F)||Ht(F)),a=()=>e.map(F=>{if(re(F))return F.value;if(Qe(F))return Ze(F);if(M(F))return Re(F,u,2)})):M(e)?t?a=()=>Re(e,u,2):a=()=>{if(!(u&&u.isUnmounted))return E&&E(),be(e,u,3,[I])}:a=me,t&&s){const F=a;a=()=>Ze(F())}let E,I=F=>{E=G.onStop=()=>{Re(F,u,4)}},q;if(Et)if(I=me,t?n&&be(t,u,3,[a(),y?[]:void 0,I]):a(),r==="sync"){const F=Ml();q=F.__watcherHandles||(F.__watcherHandles=[])}else return me;let $=y?new Array(e.length).fill(St):St;const Z=()=>{if(G.active)if(t){const F=G.run();(s||_||(y?F.some((Me,ct)=>bt(Me,$[ct])):bt(F,$)))&&(E&&E(),be(t,u,3,[F,$===St?void 0:y&&$[0]===St?[]:$,I]),$=F)}else G.run()};Z.allowRecurse=!!t;let Q;r==="sync"?Q=Z:r==="post"?Q=()=>ce(Z,u&&u.suspense):(Z.pre=!0,u&&(Z.id=u.uid),Q=()=>Un(Z));const G=new Rn(a,Q);t?n?Z():$=G.run():r==="post"?ce(G.run.bind(G),u&&u.suspense):G.run();const ee=()=>{G.stop(),u&&u.scope&&Mn(u.scope.effects,G)};return q&&q.push(ee),ee}function Do(e,t,n){const s=this.proxy,r=J(e)?e.includes(".")?ir(s,e):()=>s[e]:e.bind(s,s);let o;M(t)?o=t:(o=t.handler,n=t);const l=se;st(this);const c=lr(r,o.bind(s),n);return l?st(l):ke(),c}function ir(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;r{Ze(n,t)});else if(Ss(e))for(const n in e)Ze(e[n],t);return e}function Le(e,t,n,s){const r=e.dirs,o=t&&t.dirs;for(let l=0;lX({name:e.name},t,{setup:e}))():e}const pt=e=>!!e.type.__asyncLoader,cr=e=>e.type.__isKeepAlive;function Ho(e,t){fr(e,"a",t)}function Lo(e,t){fr(e,"da",t)}function fr(e,t,n=se){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Xt(t,s,n),n){let r=n.parent;for(;r&&r.parent;)cr(r.parent.vnode)&&Uo(s,t,n,r),r=r.parent}}function Uo(e,t,n,s){const r=Xt(t,e,s,!0);ar(()=>{Mn(s[t],r)},n)}function Xt(e,t,n=se,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...l)=>{if(n.isUnmounted)return;lt(),st(n);const c=be(t,n,e,l);return ke(),it(),c});return s?r.unshift(o):r.push(o),o}}const Ie=e=>(t,n=se)=>(!Et||e==="sp")&&Xt(e,(...s)=>t(...s),n),Ko=Ie("bm"),ur=Ie("m"),Wo=Ie("bu"),zo=Ie("u"),ko=Ie("bum"),ar=Ie("um"),qo=Ie("sp"),Yo=Ie("rtg"),Jo=Ie("rtc");function Zo(e,t=se){Xt("ec",e,t)}const Vo=Symbol.for("v-ndc");function Xo(e,t,n,s){let r;const o=n&&n[s];if(P(e)||J(e)){r=new Array(e.length);for(let l=0,c=e.length;lt(l,c,void 0,o&&o[c]));else{const l=Object.keys(e);r=new Array(l.length);for(let c=0,u=l.length;cEr(t)?!(t.type===je||t.type===de&&!hr(t.children)):!0)?e:null}const yn=e=>e?Or(e)?Yn(e)||e.proxy:yn(e.parent):null,gt=X(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>yn(e.parent),$root:e=>yn(e.root),$emit:e=>e.emit,$options:e=>Kn(e),$forceUpdate:e=>e.f||(e.f=()=>Un(e.update)),$nextTick:e=>e.n||(e.n=To.bind(e.proxy)),$watch:e=>Do.bind(e)}),un=(e,t)=>e!==L&&!e.__isScriptSetup&&R(e,t),Qo={get({_:e},t){const{ctx:n,setupState:s,data:r,props:o,accessCache:l,type:c,appContext:u}=e;let a;if(t[0]!=="$"){const I=l[t];if(I!==void 0)switch(I){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(un(s,t))return l[t]=1,s[t];if(r!==L&&R(r,t))return l[t]=2,r[t];if((a=e.propsOptions[0])&&R(a,t))return l[t]=3,o[t];if(n!==L&&R(n,t))return l[t]=4,n[t];wn&&(l[t]=0)}}const _=gt[t];let y,E;if(_)return t==="$attrs"&&ue(e,"get",t),_(e);if((y=c.__cssModules)&&(y=y[t]))return y;if(n!==L&&R(n,t))return l[t]=4,n[t];if(E=u.config.globalProperties,R(E,t))return E[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return un(r,t)?(r[t]=n,!0):s!==L&&R(s,t)?(s[t]=n,!0):R(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:o}},l){let c;return!!n[l]||e!==L&&R(e,l)||un(t,l)||(c=o[0])&&R(c,l)||R(s,l)||R(gt,l)||R(r.config.globalProperties,l)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:R(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function as(e){return P(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let wn=!0;function Go(e){const t=Kn(e),n=e.proxy,s=e.ctx;wn=!1,t.beforeCreate&&ds(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:l,watch:c,provide:u,inject:a,created:_,beforeMount:y,mounted:E,beforeUpdate:I,updated:q,activated:$,deactivated:Z,beforeDestroy:Q,beforeUnmount:G,destroyed:ee,unmounted:F,render:Me,renderTracked:ct,renderTriggered:Ct,errorCaptured:Ne,serverPrefetch:en,expose:Be,inheritAttrs:ft,components:Ot,directives:Tt,filters:tn}=t;if(a&&el(a,s,null),l)for(const z in l){const D=l[z];M(D)&&(s[z]=D.bind(n))}if(r){const z=r.call(n,n);W(z)&&(e.data=Bn(z))}if(wn=!0,o)for(const z in o){const D=o[z],De=M(D)?D.bind(n,n):M(D.get)?D.get.bind(n,n):me,Pt=!M(D)&&M(D.set)?D.set.bind(n):me,He=Pr({get:De,set:Pt});Object.defineProperty(s,z,{enumerable:!0,configurable:!0,get:()=>He.value,set:ve=>He.value=ve})}if(c)for(const z in c)pr(c[z],s,n,z);if(u){const z=M(u)?u.call(n):u;Reflect.ownKeys(z).forEach(D=>{ll(D,z[D])})}_&&ds(_,e,"c");function oe(z,D){P(D)?D.forEach(De=>z(De.bind(n))):D&&z(D.bind(n))}if(oe(Ko,y),oe(ur,E),oe(Wo,I),oe(zo,q),oe(Ho,$),oe(Lo,Z),oe(Zo,Ne),oe(Jo,ct),oe(Yo,Ct),oe(ko,G),oe(ar,F),oe(qo,en),P(Be))if(Be.length){const z=e.exposed||(e.exposed={});Be.forEach(D=>{Object.defineProperty(z,D,{get:()=>n[D],set:De=>n[D]=De})})}else e.exposed||(e.exposed={});Me&&e.render===me&&(e.render=Me),ft!=null&&(e.inheritAttrs=ft),Ot&&(e.components=Ot),Tt&&(e.directives=Tt)}function el(e,t,n=me){P(e)&&(e=En(e));for(const s in e){const r=e[s];let o;W(r)?"default"in r?o=Nt(r.from||s,r.default,!0):o=Nt(r.from||s):o=Nt(r),re(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:l=>o.value=l}):t[s]=o}}function ds(e,t,n){be(P(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function pr(e,t,n,s){const r=s.includes(".")?ir(n,s):()=>n[s];if(J(e)){const o=t[e];M(o)&&fn(r,o)}else if(M(e))fn(r,e.bind(n));else if(W(e))if(P(e))e.forEach(o=>pr(o,t,n,s));else{const o=M(e.handler)?e.handler.bind(n):t[e.handler];M(o)&&fn(r,o,e)}}function Kn(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:l}}=e.appContext,c=o.get(t);let u;return c?u=c:!r.length&&!n&&!s?u=t:(u={},r.length&&r.forEach(a=>Ut(u,a,l,!0)),Ut(u,t,l)),W(t)&&o.set(t,u),u}function Ut(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&Ut(e,o,n,!0),r&&r.forEach(l=>Ut(e,l,n,!0));for(const l in t)if(!(s&&l==="expose")){const c=tl[l]||n&&n[l];e[l]=c?c(e[l],t[l]):t[l]}return e}const tl={data:hs,props:ps,emits:ps,methods:ht,computed:ht,beforeCreate:le,created:le,beforeMount:le,mounted:le,beforeUpdate:le,updated:le,beforeDestroy:le,beforeUnmount:le,destroyed:le,unmounted:le,activated:le,deactivated:le,errorCaptured:le,serverPrefetch:le,components:ht,directives:ht,watch:sl,provide:hs,inject:nl};function hs(e,t){return t?e?function(){return X(M(e)?e.call(this,this):e,M(t)?t.call(this,this):t)}:t:e}function nl(e,t){return ht(En(e),En(t))}function En(e){if(P(e)){const t={};for(let n=0;n1)return n&&M(t)?t.call(s&&s.proxy):t}}function il(e,t,n,s=!1){const r={},o={};Dt(o,Gt,1),e.propsDefaults=Object.create(null),_r(e,t,r,o);for(const l in e.propsOptions[0])l in r||(r[l]=void 0);n?e.props=s?r:vo(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function cl(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:l}}=e,c=j(r),[u]=e.propsOptions;let a=!1;if((s||l>0)&&!(l&16)){if(l&8){const _=e.vnode.dynamicProps;for(let y=0;y<_.length;y++){let E=_[y];if(Zt(e.emitsOptions,E))continue;const I=t[E];if(u)if(R(o,E))I!==o[E]&&(o[E]=I,a=!0);else{const q=et(E);r[q]=Cn(u,c,q,I,e,!1)}else I!==o[E]&&(o[E]=I,a=!0)}}}else{_r(e,t,r,o)&&(a=!0);let _;for(const y in c)(!t||!R(t,y)&&((_=rt(y))===y||!R(t,_)))&&(u?n&&(n[y]!==void 0||n[_]!==void 0)&&(r[y]=Cn(u,c,y,void 0,e,!0)):delete r[y]);if(o!==c)for(const y in o)(!t||!R(t,y))&&(delete o[y],a=!0)}a&&Pe(e,"set","$attrs")}function _r(e,t,n,s){const[r,o]=e.propsOptions;let l=!1,c;if(t)for(let u in t){if(jt(u))continue;const a=t[u];let _;r&&R(r,_=et(u))?!o||!o.includes(_)?n[_]=a:(c||(c={}))[_]=a:Zt(e.emitsOptions,u)||(!(u in s)||a!==s[u])&&(s[u]=a,l=!0)}if(o){const u=j(n),a=c||L;for(let _=0;_{u=!0;const[E,I]=mr(y,t,!0);X(l,E),I&&c.push(...I)};!n&&t.mixins.length&&t.mixins.forEach(_),e.extends&&_(e.extends),e.mixins&&e.mixins.forEach(_)}if(!o&&!u)return W(e)&&s.set(e,Ve),Ve;if(P(o))for(let _=0;_-1,I[1]=$<0||q<$,(q>-1||R(I,"default"))&&c.push(y)}}}const a=[l,c];return W(e)&&s.set(e,a),a}function gs(e){return e[0]!=="$"}function _s(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function ms(e,t){return _s(e)===_s(t)}function bs(e,t){return P(t)?t.findIndex(n=>ms(n,e)):M(t)&&ms(t,e)?0:-1}const br=e=>e[0]==="_"||e==="$stable",Wn=e=>P(e)?e.map(Ee):[Ee(e)],fl=(e,t,n)=>{if(t._n)return t;const s=te((...r)=>Wn(t(...r)),n);return s._c=!1,s},vr=(e,t,n)=>{const s=e._ctx;for(const r in e){if(br(r))continue;const o=e[r];if(M(o))t[r]=fl(r,o,s);else if(o!=null){const l=Wn(o);t[r]=()=>l}}},xr=(e,t)=>{const n=Wn(t);e.slots.default=()=>n},ul=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=j(t),Dt(t,"_",n)):vr(t,e.slots={})}else e.slots={},t&&xr(e,t);Dt(e.slots,Gt,1)},al=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,l=L;if(s.shapeFlag&32){const c=t._;c?n&&c===1?o=!1:(X(r,t),!n&&c===1&&delete r._):(o=!t.$stable,vr(t,r)),l=t}else t&&(xr(e,t),l={default:1});if(o)for(const c in r)!br(c)&&!(c in l)&&delete r[c]};function On(e,t,n,s,r=!1){if(P(e)){e.forEach((E,I)=>On(E,t&&(P(t)?t[I]:t),n,s,r));return}if(pt(s)&&!r)return;const o=s.shapeFlag&4?Yn(s.component)||s.component.proxy:s.el,l=r?null:o,{i:c,r:u}=e,a=t&&t.r,_=c.refs===L?c.refs={}:c.refs,y=c.setupState;if(a!=null&&a!==u&&(J(a)?(_[a]=null,R(y,a)&&(y[a]=null)):re(a)&&(a.value=null)),M(u))Re(u,c,12,[l,_]);else{const E=J(u),I=re(u);if(E||I){const q=()=>{if(e.f){const $=E?R(y,u)?y[u]:_[u]:u.value;r?P($)&&Mn($,o):P($)?$.includes(o)||$.push(o):E?(_[u]=[o],R(y,u)&&(y[u]=_[u])):(u.value=[o],e.k&&(_[e.k]=u.value))}else E?(_[u]=l,R(y,u)&&(y[u]=l)):I&&(u.value=l,e.k&&(_[e.k]=l))};l?(q.id=-1,ce(q,n)):q()}}}const ce=Bo;function dl(e){return hl(e)}function hl(e,t){const n=gn();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:l,createText:c,createComment:u,setText:a,setElementText:_,parentNode:y,nextSibling:E,setScopeId:I=me,insertStaticContent:q}=e,$=(i,f,d,p=null,h=null,b=null,x=!1,m=null,v=!!f.dynamicChildren)=>{if(i===f)return;i&&!at(i,f)&&(p=It(i),ve(i,h,b,!0),i=null),f.patchFlag===-2&&(v=!1,f.dynamicChildren=null);const{type:g,ref:C,shapeFlag:w}=f;switch(g){case Qt:Z(i,f,d,p);break;case je:Q(i,f,d,p);break;case an:i==null&&G(f,d,p,x);break;case de:Ot(i,f,d,p,h,b,x,m,v);break;default:w&1?Me(i,f,d,p,h,b,x,m,v):w&6?Tt(i,f,d,p,h,b,x,m,v):(w&64||w&128)&&g.process(i,f,d,p,h,b,x,m,v,qe)}C!=null&&h&&On(C,i&&i.ref,b,f||i,!f)},Z=(i,f,d,p)=>{if(i==null)s(f.el=c(f.children),d,p);else{const h=f.el=i.el;f.children!==i.children&&a(h,f.children)}},Q=(i,f,d,p)=>{i==null?s(f.el=u(f.children||""),d,p):f.el=i.el},G=(i,f,d,p)=>{[i.el,i.anchor]=q(i.children,f,d,p,i.el,i.anchor)},ee=({el:i,anchor:f},d,p)=>{let h;for(;i&&i!==f;)h=E(i),s(i,d,p),i=h;s(f,d,p)},F=({el:i,anchor:f})=>{let d;for(;i&&i!==f;)d=E(i),r(i),i=d;r(f)},Me=(i,f,d,p,h,b,x,m,v)=>{x=x||f.type==="svg",i==null?ct(f,d,p,h,b,x,m,v):en(i,f,h,b,x,m,v)},ct=(i,f,d,p,h,b,x,m)=>{let v,g;const{type:C,props:w,shapeFlag:O,transition:T,dirs:A}=i;if(v=i.el=l(i.type,b,w&&w.is,w),O&8?_(v,i.children):O&16&&Ne(i.children,v,null,p,h,b&&C!=="foreignObject",x,m),A&&Le(i,null,p,"created"),Ct(v,i,i.scopeId,x,p),w){for(const B in w)B!=="value"&&!jt(B)&&o(v,B,null,w[B],b,i.children,p,h,Oe);"value"in w&&o(v,"value",null,w.value),(g=w.onVnodeBeforeMount)&&ye(g,p,i)}A&&Le(i,null,p,"beforeMount");const H=(!h||h&&!h.pendingBranch)&&T&&!T.persisted;H&&T.beforeEnter(v),s(v,f,d),((g=w&&w.onVnodeMounted)||H||A)&&ce(()=>{g&&ye(g,p,i),H&&T.enter(v),A&&Le(i,null,p,"mounted")},h)},Ct=(i,f,d,p,h)=>{if(d&&I(i,d),p)for(let b=0;b{for(let g=v;g{const m=f.el=i.el;let{patchFlag:v,dynamicChildren:g,dirs:C}=f;v|=i.patchFlag&16;const w=i.props||L,O=f.props||L;let T;d&&Ue(d,!1),(T=O.onVnodeBeforeUpdate)&&ye(T,d,f,i),C&&Le(f,i,d,"beforeUpdate"),d&&Ue(d,!0);const A=h&&f.type!=="foreignObject";if(g?Be(i.dynamicChildren,g,m,d,p,A,b):x||D(i,f,m,null,d,p,A,b,!1),v>0){if(v&16)ft(m,f,w,O,d,p,h);else if(v&2&&w.class!==O.class&&o(m,"class",null,O.class,h),v&4&&o(m,"style",w.style,O.style,h),v&8){const H=f.dynamicProps;for(let B=0;B{T&&ye(T,d,f,i),C&&Le(f,i,d,"updated")},p)},Be=(i,f,d,p,h,b,x)=>{for(let m=0;m{if(d!==p){if(d!==L)for(const m in d)!jt(m)&&!(m in p)&&o(i,m,d[m],null,x,f.children,h,b,Oe);for(const m in p){if(jt(m))continue;const v=p[m],g=d[m];v!==g&&m!=="value"&&o(i,m,g,v,x,f.children,h,b,Oe)}"value"in p&&o(i,"value",d.value,p.value)}},Ot=(i,f,d,p,h,b,x,m,v)=>{const g=f.el=i?i.el:c(""),C=f.anchor=i?i.anchor:c("");let{patchFlag:w,dynamicChildren:O,slotScopeIds:T}=f;T&&(m=m?m.concat(T):T),i==null?(s(g,d,p),s(C,d,p),Ne(f.children,d,C,h,b,x,m,v)):w>0&&w&64&&O&&i.dynamicChildren?(Be(i.dynamicChildren,O,d,h,b,x,m),(f.key!=null||h&&f===h.subTree)&&yr(i,f,!0)):D(i,f,d,C,h,b,x,m,v)},Tt=(i,f,d,p,h,b,x,m,v)=>{f.slotScopeIds=m,i==null?f.shapeFlag&512?h.ctx.activate(f,d,p,x,v):tn(f,d,p,h,b,x,v):Zn(i,f,v)},tn=(i,f,d,p,h,b,x)=>{const m=i.component=wl(i,p,h);if(cr(i)&&(m.ctx.renderer=qe),El(m),m.asyncDep){if(h&&h.registerDep(m,oe),!i.el){const v=m.subTree=S(je);Q(null,v,f,d)}return}oe(m,i,f,d,h,b,x)},Zn=(i,f,d)=>{const p=f.component=i.component;if(So(i,f,d))if(p.asyncDep&&!p.asyncResolved){z(p,f,d);return}else p.next=f,Io(p.update),p.update();else f.el=i.el,p.vnode=f},oe=(i,f,d,p,h,b,x)=>{const m=()=>{if(i.isMounted){let{next:C,bu:w,u:O,parent:T,vnode:A}=i,H=C,B;Ue(i,!1),C?(C.el=A.el,z(i,C,x)):C=A,w&&on(w),(B=C.props&&C.props.onVnodeBeforeUpdate)&&ye(B,T,C,A),Ue(i,!0);const Y=cn(i),he=i.subTree;i.subTree=Y,$(he,Y,y(he.el),It(he),i,h,b),C.el=Y.el,H===null&&jo(i,Y.el),O&&ce(O,h),(B=C.props&&C.props.onVnodeUpdated)&&ce(()=>ye(B,T,C,A),h)}else{let C;const{el:w,props:O}=f,{bm:T,m:A,parent:H}=i,B=pt(f);if(Ue(i,!1),T&&on(T),!B&&(C=O&&O.onVnodeBeforeMount)&&ye(C,H,f),Ue(i,!0),w&&sn){const Y=()=>{i.subTree=cn(i),sn(w,i.subTree,i,h,null)};B?f.type.__asyncLoader().then(()=>!i.isUnmounted&&Y()):Y()}else{const Y=i.subTree=cn(i);$(null,Y,d,p,i,h,b),f.el=Y.el}if(A&&ce(A,h),!B&&(C=O&&O.onVnodeMounted)){const Y=f;ce(()=>ye(C,H,Y),h)}(f.shapeFlag&256||H&&pt(H.vnode)&&H.vnode.shapeFlag&256)&&i.a&&ce(i.a,h),i.isMounted=!0,f=d=p=null}},v=i.effect=new Rn(m,()=>Un(g),i.scope),g=i.update=()=>v.run();g.id=i.uid,Ue(i,!0),g()},z=(i,f,d)=>{f.component=i;const p=i.vnode.props;i.vnode=f,i.next=null,cl(i,f.props,p,d),al(i,f.children,d),lt(),fs(),it()},D=(i,f,d,p,h,b,x,m,v=!1)=>{const g=i&&i.children,C=i?i.shapeFlag:0,w=f.children,{patchFlag:O,shapeFlag:T}=f;if(O>0){if(O&128){Pt(g,w,d,p,h,b,x,m,v);return}else if(O&256){De(g,w,d,p,h,b,x,m,v);return}}T&8?(C&16&&Oe(g,h,b),w!==g&&_(d,w)):C&16?T&16?Pt(g,w,d,p,h,b,x,m,v):Oe(g,h,b,!0):(C&8&&_(d,""),T&16&&Ne(w,d,p,h,b,x,m,v))},De=(i,f,d,p,h,b,x,m,v)=>{i=i||Ve,f=f||Ve;const g=i.length,C=f.length,w=Math.min(g,C);let O;for(O=0;OC?Oe(i,h,b,!0,!1,w):Ne(f,d,p,h,b,x,m,v,w)},Pt=(i,f,d,p,h,b,x,m,v)=>{let g=0;const C=f.length;let w=i.length-1,O=C-1;for(;g<=w&&g<=O;){const T=i[g],A=f[g]=v?Ae(f[g]):Ee(f[g]);if(at(T,A))$(T,A,d,null,h,b,x,m,v);else break;g++}for(;g<=w&&g<=O;){const T=i[w],A=f[O]=v?Ae(f[O]):Ee(f[O]);if(at(T,A))$(T,A,d,null,h,b,x,m,v);else break;w--,O--}if(g>w){if(g<=O){const T=O+1,A=TO)for(;g<=w;)ve(i[g],h,b,!0),g++;else{const T=g,A=g,H=new Map;for(g=A;g<=O;g++){const ae=f[g]=v?Ae(f[g]):Ee(f[g]);ae.key!=null&&H.set(ae.key,g)}let B,Y=0;const he=O-A+1;let Ye=!1,Qn=0;const ut=new Array(he);for(g=0;g=he){ve(ae,h,b,!0);continue}let xe;if(ae.key!=null)xe=H.get(ae.key);else for(B=A;B<=O;B++)if(ut[B-A]===0&&at(ae,f[B])){xe=B;break}xe===void 0?ve(ae,h,b,!0):(ut[xe-A]=g+1,xe>=Qn?Qn=xe:Ye=!0,$(ae,f[xe],d,null,h,b,x,m,v),Y++)}const Gn=Ye?pl(ut):Ve;for(B=Gn.length-1,g=he-1;g>=0;g--){const ae=A+g,xe=f[ae],es=ae+1{const{el:b,type:x,transition:m,children:v,shapeFlag:g}=i;if(g&6){He(i.component.subTree,f,d,p);return}if(g&128){i.suspense.move(f,d,p);return}if(g&64){x.move(i,f,d,qe);return}if(x===de){s(b,f,d);for(let w=0;wm.enter(b),h);else{const{leave:w,delayLeave:O,afterLeave:T}=m,A=()=>s(b,f,d),H=()=>{w(b,()=>{A(),T&&T()})};O?O(b,A,H):H()}else s(b,f,d)},ve=(i,f,d,p=!1,h=!1)=>{const{type:b,props:x,ref:m,children:v,dynamicChildren:g,shapeFlag:C,patchFlag:w,dirs:O}=i;if(m!=null&&On(m,null,d,i,!0),C&256){f.ctx.deactivate(i);return}const T=C&1&&O,A=!pt(i);let H;if(A&&(H=x&&x.onVnodeBeforeUnmount)&&ye(H,f,i),C&6)Mr(i.component,d,p);else{if(C&128){i.suspense.unmount(d,p);return}T&&Le(i,null,f,"beforeUnmount"),C&64?i.type.remove(i,f,d,h,qe,p):g&&(b!==de||w>0&&w&64)?Oe(g,f,d,!1,!0):(b===de&&w&384||!h&&C&16)&&Oe(v,f,d),p&&Vn(i)}(A&&(H=x&&x.onVnodeUnmounted)||T)&&ce(()=>{H&&ye(H,f,i),T&&Le(i,null,f,"unmounted")},d)},Vn=i=>{const{type:f,el:d,anchor:p,transition:h}=i;if(f===de){Ir(d,p);return}if(f===an){F(i);return}const b=()=>{r(d),h&&!h.persisted&&h.afterLeave&&h.afterLeave()};if(i.shapeFlag&1&&h&&!h.persisted){const{leave:x,delayLeave:m}=h,v=()=>x(d,b);m?m(i.el,b,v):v()}else b()},Ir=(i,f)=>{let d;for(;i!==f;)d=E(i),r(i),i=d;r(f)},Mr=(i,f,d)=>{const{bum:p,scope:h,update:b,subTree:x,um:m}=i;p&&on(p),h.stop(),b&&(b.active=!1,ve(x,i,f,d)),m&&ce(m,f),ce(()=>{i.isUnmounted=!0},f),f&&f.pendingBranch&&!f.isUnmounted&&i.asyncDep&&!i.asyncResolved&&i.suspenseId===f.pendingId&&(f.deps--,f.deps===0&&f.resolve())},Oe=(i,f,d,p=!1,h=!1,b=0)=>{for(let x=b;xi.shapeFlag&6?It(i.component.subTree):i.shapeFlag&128?i.suspense.next():E(i.anchor||i.el),Xn=(i,f,d)=>{i==null?f._vnode&&ve(f._vnode,null,null,!0):$(f._vnode||null,i,f,null,null,null,d),fs(),nr(),f._vnode=i},qe={p:$,um:ve,m:He,r:Vn,mt:tn,mc:Ne,pc:D,pbc:Be,n:It,o:e};let nn,sn;return t&&([nn,sn]=t(qe)),{render:Xn,hydrate:nn,createApp:ol(Xn,nn)}}function Ue({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function yr(e,t,n=!1){const s=e.children,r=t.children;if(P(s)&&P(r))for(let o=0;o>1,e[n[c]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,l=n[o-1];o-- >0;)n[o]=l,l=t[l];return n}const gl=e=>e.__isTeleport,de=Symbol.for("v-fgt"),Qt=Symbol.for("v-txt"),je=Symbol.for("v-cmt"),an=Symbol.for("v-stc"),_t=[];let _e=null;function V(e=!1){_t.push(_e=e?null:[])}function _l(){_t.pop(),_e=_t[_t.length-1]||null}let wt=1;function vs(e){wt+=e}function wr(e){return e.dynamicChildren=wt>0?_e||Ve:null,_l(),wt>0&&_e&&_e.push(e),e}function ie(e,t,n,s,r,o){return wr(K(e,t,n,s,r,o,!0))}function zn(e,t,n,s,r){return wr(S(e,t,n,s,r,!0))}function Er(e){return e?e.__v_isVNode===!0:!1}function at(e,t){return e.type===t.type&&e.key===t.key}const Gt="__vInternal",Cr=({key:e})=>e??null,Bt=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?J(e)||re(e)||M(e)?{i:fe,r:e,k:t,f:!!n}:e:null);function K(e,t=null,n=null,s=0,r=null,o=e===de?0:1,l=!1,c=!1){const u={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Cr(t),ref:t&&Bt(t),scopeId:or,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:fe};return c?(kn(u,n),o&128&&e.normalize(u)):n&&(u.shapeFlag|=J(n)?8:16),wt>0&&!l&&_e&&(u.patchFlag>0||o&6)&&u.patchFlag!==32&&_e.push(u),u}const S=ml;function ml(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===Vo)&&(e=je),Er(e)){const c=nt(e,t,!0);return n&&kn(c,n),wt>0&&!o&&_e&&(c.shapeFlag&6?_e[_e.indexOf(e)]=c:_e.push(c)),c.patchFlag|=-2,c}if(Pl(e)&&(e=e.__vccOpts),t){t=bl(t);let{class:c,style:u}=t;c&&!J(c)&&(t.class=ot(c)),W(u)&&(Zs(u)&&!P(u)&&(u=X({},u)),t.style=qt(u))}const l=J(e)?1:No(e)?128:gl(e)?64:W(e)?4:M(e)?2:0;return K(e,t,n,s,r,l,o,!0)}function bl(e){return e?Zs(e)||Gt in e?X({},e):e:null}function nt(e,t,n=!1){const{props:s,ref:r,patchFlag:o,children:l}=e,c=t?vl(s||{},t):s;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:c,key:c&&Cr(c),ref:t&&t.ref?n&&r?P(r)?r.concat(Bt(t)):[r,Bt(t)]:Bt(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==de?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&nt(e.ssContent),ssFallback:e.ssFallback&&nt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function N(e=" ",t=0){return S(Qt,null,e,t)}function mt(e="",t=!1){return t?(V(),zn(je,null,e)):S(je,null,e)}function Ee(e){return e==null||typeof e=="boolean"?S(je):P(e)?S(de,null,e.slice()):typeof e=="object"?Ae(e):S(Qt,null,String(e))}function Ae(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:nt(e)}function kn(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(P(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),kn(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!(Gt in t)?t._ctx=fe:r===3&&fe&&(fe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else M(t)?(t={default:t,_ctx:fe},n=32):(t=String(t),s&64?(n=16,t=[N(t)]):n=8);e.children=t,e.shapeFlag|=n}function vl(...e){const t={};for(let n=0;nse=e),qn=e=>{Je.length>1?Je.forEach(t=>t(e)):Je[0](e)};const st=e=>{qn(e),e.scope.on()},ke=()=>{se&&se.scope.off(),qn(null)};function Or(e){return e.vnode.shapeFlag&4}let Et=!1;function El(e,t=!1){Et=t;const{props:n,children:s}=e.vnode,r=Or(e);il(e,n,r,t),ul(e,s);const o=r?Cl(e,t):void 0;return Et=!1,o}function Cl(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=Vs(new Proxy(e.ctx,Qo));const{setup:s}=n;if(s){const r=e.setupContext=s.length>1?Tl(e):null;st(e),lt();const o=Re(s,e,0,[e.props,r]);if(it(),ke(),$s(o)){if(o.then(ke,ke),t)return o.then(l=>{ys(e,l,t)}).catch(l=>{Jt(l,e,0)});e.asyncDep=o}else ys(e,o,t)}else Tr(e,t)}function ys(e,t,n){M(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:W(t)&&(e.setupState=Gs(t)),Tr(e,n)}let ws;function Tr(e,t,n){const s=e.type;if(!e.render){if(!t&&ws&&!s.render){const r=s.template||Kn(e).template;if(r){const{isCustomElement:o,compilerOptions:l}=e.appContext.config,{delimiters:c,compilerOptions:u}=s,a=X(X({isCustomElement:o,delimiters:c},l),u);s.render=ws(r,a)}}e.render=s.render||me}st(e),lt(),Go(e),it(),ke()}function Ol(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return ue(e,"get","$attrs"),t[n]}}))}function Tl(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return Ol(e)},slots:e.slots,emit:e.emit,expose:t}}function Yn(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Gs(Vs(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in gt)return gt[n](e)},has(t,n){return n in t||n in gt}}))}function Pl(e){return M(e)&&"__vccOpts"in e}const Pr=(e,t)=>Co(e,t,Et),Il=Symbol.for("v-scx"),Ml=()=>Nt(Il),Fl="3.3.4",Al="http://www.w3.org/2000/svg",We=typeof document<"u"?document:null,Es=We&&We.createElement("template"),$l={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t?We.createElementNS(Al,e):We.createElement(e,n?{is:n}:void 0);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>We.createTextNode(e),createComment:e=>We.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>We.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const l=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{Es.innerHTML=s?`${e}`:e;const c=Es.content;if(s){const u=c.firstChild;for(;u.firstChild;)c.appendChild(u.firstChild);c.removeChild(u)}t.insertBefore(c,n)}return[l?l.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};function Rl(e,t,n){const s=e._vtc;s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}function Sl(e,t,n){const s=e.style,r=J(n);if(n&&!r){if(t&&!J(t))for(const o in t)n[o]==null&&Tn(s,o,"");for(const o in n)Tn(s,o,n[o])}else{const o=s.display;r?t!==n&&(s.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(s.display=o)}}const Cs=/\s*!important$/;function Tn(e,t,n){if(P(n))n.forEach(s=>Tn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=jl(e,t);Cs.test(n)?e.setProperty(rt(s),n.replace(Cs,""),"important"):e[s]=n}}const Os=["Webkit","Moz","ms"],dn={};function jl(e,t){const n=dn[t];if(n)return n;let s=et(t);if(s!=="filter"&&s in e)return dn[t]=s;s=js(s);for(let r=0;rhn||(Kl.then(()=>hn=0),hn=Date.now());function zl(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;be(kl(s,n.value),t,5,[s])};return n.value=e,n.attached=Wl(),n}function kl(e,t){if(P(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const Is=/^on[a-z]/,ql=(e,t,n,s,r=!1,o,l,c,u)=>{t==="class"?Rl(e,s,r):t==="style"?Sl(e,n,s):Wt(t)?In(t)||Ll(e,t,n,s,l):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Yl(e,t,s,r))?Bl(e,t,s,o,l,c,u):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Nl(e,t,s,r))};function Yl(e,t,n,s){return s?!!(t==="innerHTML"||t==="textContent"||t in e&&Is.test(t)&&M(n)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||Is.test(t)&&J(n)?!1:t in e}const Jl=X({patchProp:ql},$l);let Ms;function Zl(){return Ms||(Ms=dl(Jl))}const Vl=(...e)=>{const t=Zl().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Xl(s);if(!r)return;const o=t._component;!M(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.innerHTML="";const l=n(r,!1,r instanceof SVGElement);return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),l},t};function Xl(e){return J(e)?document.querySelector(e):e}const Jn=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Ql={},Gl={xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},ei=K("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18"},null,-1),ti=[ei];function ni(e,t){return V(),ie("svg",Gl,ti)}const si=Jn(Ql,[["render",ni]]),ri={},oi={xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},li=K("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3"},null,-1),ii=[li];function ci(e,t){return V(),ie("svg",oi,ii)}const fi=Jn(ri,[["render",ci]]),ui={class:"inline-block text-sm bg-gray-200 rounded-full overflow-hidden relative"},ai=Vt({__name:"Progress",props:{value:{},max:{}},setup(e){return(t,n)=>(V(),ie("div",ui,[K("div",{class:ot(["px-2 text-sm transition-[width] duration-500 whitespace-nowrap",{"bg-gray-400/50":t.value/t.max<.8,"bg-orange-300":t.value/t.max>=.8&&t.value/t.max<.9,"bg-red-300":t.value/t.max>=.9}]),style:qt({width:`${t.value/t.max*100}%`})},[dr(t.$slots,"default")],6)]))}}),di={},hi={class:"inline-block bg-gray-200 px-2 rounded-full text-sm"};function pi(e,t){return V(),ie("div",hi,[dr(e.$slots,"default")])}const gi=Jn(di,[["render",pi]]),_i=Vt({__name:"StatusIndicator",props:{status:{type:Boolean}},setup(e){return(t,n)=>(V(),ie("div",{class:ot(["rounded-full inline-block",{"bg-green-400":t.status,"bg-red-500":!t.status}])},null,2))}});function we(e,t=2){if(e===0)return"0 B";const n=1024,s=t<0?0:t,r=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],o=Math.floor(Math.log(e)/Math.log(n));return`${Number.parseFloat((e/n**o).toFixed(s))} ${r[o]}`}function mi(e){const t=new Date(e*1e3),n=t.getFullYear(),s=(t.getMonth()+1).toString().padStart(2,"0"),r=t.getDate().toString().padStart(2,"0"),o=t.getHours().toString().padStart(2,"0"),l=t.getMinutes().toString().padStart(2,"0"),c=t.getSeconds().toString().padStart(2,"0");return`${n}/${s}/${r} ${o}:${l}:${c}`}function pn(e){return e.online4||e.online6}function bi(e){return/[\uD800-\uDBFF][\uDC00-\uDFFF]/g.test(e)}const vi={class:"rounded-xl px-4 py-3 transition-all relative bg-gray-100 border border-transparent hover:border-gray-400 hover:shadow-md hover:bg-white duration-300"},xi={class:"absolute right-4 top-4 group flex flex-col items-end"},yi={class:"hidden group-hover:block p-2 rounded-xl border text-sm bg-white z-[9999] mt-1 border-gray-400"},wi={class:"flex gap-2"},Ei={class:"flex items-center gap-1"},Ci={class:"flex items-center gap-1"},Oi={key:0},Ti=K("br",null,null,-1),Pi={class:"text-lg flex items-center gap-2"},Ii={key:0},Mi=["src","alt"],Fi=["src","alt"],Ai={class:"flex items-center gap-2"},$i={class:"flex items-center gap-2"},Ri={class:"flex items-center gap-2"},Si={class:"flex items-center gap-2"},ji={class:"flex items-center gap-2"},Ni={class:"flex items-center gap-2"},Bi={class:"flex gap-1 flex-wrap mt-1"},Di=Vt({__name:"ServerItem",props:{server:{}},setup(e){const t=e,n=Pr(()=>{if(!t.server.labels)return{};const s=t.server.labels.split(";"),r={};return s.forEach(o=>{if(o==="")return;const[l,c]=o.split("=");r[l]=c}),r});return(s,r)=>{const o=_i,l=gi,c=ai,u=fi,a=si;return V(),ie("div",vi,[K("div",xi,[S(o,{status:U(pn)(s.server),class:"w-3 h-3"},null,8,["status"]),K("div",yi,[K("div",wi,[K("div",Ei,[N(" IPv4 "),S(o,{status:s.server.online4,class:"w-2 h-2"},null,8,["status"])]),K("div",Ci,[N(" IPv6 "),S(o,{status:s.server.online6,class:"w-2 h-2"},null,8,["status"])])]),s.server.latest_ts?(V(),ie("div",Oi,[N(" 最后上报时间"),Ti,N(" "+k(U(mi)(s.server.latest_ts)),1)])):mt("",!0)])]),K("div",Pi,[U(bi)(s.server.location)?(V(),ie("span",Ii,k(s.server.location),1)):(V(),ie("img",{key:1,src:`/image/flags/${s.server.location}.svg`,alt:`${s.server.location} flag`,class:"h-4 inline-block rounded-sm"},null,8,Mi)),U(n).os?(V(),ie("img",{key:2,src:`/image/os/${U(n).os}.svg`,alt:`${U(n).os} os`,class:"h-4 inline-block rounded-sm"},null,8,Fi)):mt("",!0),N(" "+k(s.server.alias||s.server.name),1)]),K("div",null,[N(" 运行时间 "),K("span",{class:ot({"text-red-500":!U(pn)(s.server)})},k(U(pn)(s.server)?s.server.uptime:"离线"),3)]),K("div",Ai,[N(" 负载 "),S(l,null,{default:te(()=>[N(k(s.server.load_1),1)]),_:1}),S(l,null,{default:te(()=>[N(k(s.server.load_5),1)]),_:1}),S(l,null,{default:te(()=>[N(k(s.server.load_15),1)]),_:1})]),K("div",$i,[N(" CPU "),S(c,{value:s.server.cpu,max:100,text:`${s.server.cpu}%`,class:"flex-1"},{default:te(()=>[N(k(s.server.cpu)+"% ",1)]),_:1},8,["value","text"])]),K("div",Ri,[N(" 内存 "),S(c,{value:s.server.memory_used,max:s.server.memory_total,class:"flex-1"},{default:te(()=>[N(k(U(we)(s.server.memory_used*1024))+" / "+k(U(we)(s.server.memory_total*1024)),1)]),_:1},8,["value","max"])]),K("div",Si,[N(" 硬盘 "),S(c,{value:s.server.hdd_used,max:s.server.hdd_total,class:"flex-1"},{default:te(()=>[N(k(U(we)(s.server.hdd_used*1024*1024))+" / "+k(U(we)(s.server.hdd_total*1024*1024)),1)]),_:1},8,["value","max"])]),K("div",ji,[N(" 网络 "),S(l,{class:"flex items-center"},{default:te(()=>[S(u,{class:"w-4 h-4"}),N(k(U(we)(s.server.network_rx,1))+"/s ",1)]),_:1}),S(l,{class:"flex items-center"},{default:te(()=>[S(a,{class:"w-4 h-4"}),N(k(U(we)(s.server.network_tx,1))+"/s ",1)]),_:1})]),K("div",Ni,[N(" 流量 "),S(l,{class:"flex items-center"},{default:te(()=>[S(u,{class:"w-4 h-4"}),N(k(U(we)(s.server.network_in,1)),1)]),_:1}),S(l,{class:"flex items-center"},{default:te(()=>[S(a,{class:"w-4 h-4"}),N(k(U(we)(s.server.network_out,1)),1)]),_:1})]),K("div",null,[N(" SWAP "),S(l,null,{default:te(()=>[N(k(U(we)(s.server.swap_used*1024))+" / "+k(U(we)(s.server.swap_total*1024)),1)]),_:1})]),K("div",Bi,[S(l,null,{default:te(()=>[N(" TCP "+k(s.server.tcp_count),1)]),_:1}),S(l,null,{default:te(()=>[N(" UDP "+k(s.server.udp_count),1)]),_:1}),S(l,null,{default:te(()=>[N(" 进程 "+k(s.server.process_count),1)]),_:1}),S(l,null,{default:te(()=>[N(" 线程 "+k(s.server.thread_count),1)]),_:1})])])}}}),Hi={key:0,class:"w-fit mx-auto my-2"},Li={key:1,class:"w-fit mx-auto my-2"},Ui={key:2,class:"flex flex-wrap gap-x-4 gap-y-3"},Ki=K("div",{class:"h-16"},null,-1),Fs="/json/stats.json",Wi=Vt({__name:"App",setup(e){const t=ln(),n=ln(!0),s=ln(!1);ur(()=>{fetch(Fs).then(o=>o.json()).then(o=>{t.value=o,setInterval(()=>{r()},1e3)}).catch(()=>{s.value=!0}).finally(()=>{n.value=!1})});function r(){fetch(Fs).then(o=>o.json()).then(o=>{t.value=o,s.value=!1}).catch(()=>{s.value=!0})}return(o,l)=>{const c=Di;return V(),ie(de,null,[U(n)?(V(),ie("div",Hi," 加载中 ")):mt("",!0),U(s)?(V(),ie("div",Li," 数据加载失败,请尝试刷新页面或检查 ServerStatus 服务端状态 ")):mt("",!0),U(t)?(V(),ie("div",Ui,[(V(!0),ie(de,null,Xo(U(t).servers,u=>(V(),zn(c,{key:u.name,server:u,class:"flex-1 min-w-[300px]"},null,8,["server"]))),128))])):mt("",!0),Ki],64)}}});const zi=Vl(Wi);zi.mount("#app"); diff --git a/web/index3.html b/web/index3.html index 2f37a01b..bcd7ccdc 100644 --- a/web/index3.html +++ b/web/index3.html @@ -6,7 +6,7 @@ ServerStatus - + From 4a9f5adb6bd3cadd87372dcabc48ed2bd1300fb4 Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 17 Oct 2023 09:49:44 +0800 Subject: [PATCH 018/134] Update index3.html cppla/Serverstatus version modify --- web/index3.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/index3.html b/web/index3.html index bcd7ccdc..ac2a1902 100644 --- a/web/index3.html +++ b/web/index3.html @@ -17,8 +17,8 @@

- Powered by ServerStatus-Rust. + Powered by ServerStatus中文版. Theme Light by OriLight
From 5ebf076330ce911f32cb932e463544534e58155c Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Mon, 1 Jan 2024 00:00:00 +0000 Subject: [PATCH 019/134] Update ExprTk to 0.0.3 --- server/src/exprtk.hpp | 13501 +++++++++++++++++++++++++++------------- 1 file changed, 9292 insertions(+), 4209 deletions(-) diff --git a/server/src/exprtk.hpp b/server/src/exprtk.hpp index b4530ba0..da493c59 100644 --- a/server/src/exprtk.hpp +++ b/server/src/exprtk.hpp @@ -2,7 +2,7 @@ ****************************************************************** * C++ Mathematical Expression Toolkit Library * * * - * Author: Arash Partow (1999-2023) * + * Author: Arash Partow (1999-2024) * * URL: https://www.partow.net/programming/exprtk/index.html * * * * Copyright notice: * @@ -10,6 +10,7 @@ * permitted under the guidelines and in accordance with the most * * current version of the MIT License. * * https://www.opensource.org/licenses/MIT * + * SPDX-License-Identifier: MIT * * * * Example expressions: * * (00) (y + x / y) * (x - y / x) * @@ -17,12 +18,12 @@ * (02) sqrt(1 - (x^2)) * * (03) 1 - sin(2 * x) + cos(pi / y) * * (04) a * exp(2 * t) + c * - * (05) if(((x + 2) == 3) and ((y + 5) <= 9),1 + w, 2 / z) * + * (05) if(((x + 2) == 3) and ((y + 5) <= 9), 1 + w, 2 / z) * * (06) (avg(x,y) <= x + y ? x - y : x * y) + 2 * pi / x * * (07) z := x + sin(2 * pi / y) * * (08) u := 2 * (pi * z) / (w := x + cos(y / pi)) * - * (09) clamp(-1,sin(2 * pi * x) + cos(y / 2 * pi),+1) * - * (10) inrange(-2,m,+2) == if(({-2 <= m} and [m <= +2]),1,0) * + * (09) clamp(-1, sin(2 * pi * x) + cos(y / 2 * pi), +1) * + * (10) inrange(-2, m, +2) == if(({-2 <= m} and [m <= +2]), 1, 0) * * (11) (2sin(x)cos(2y)7 + 1) == (2 * sin(x) * cos(2*y) * 7 + 1) * * (12) (x ilike 's*ri?g') and [y < (3 z^7 + w)] * * * @@ -42,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -67,20 +67,6 @@ namespace exprtk #define exprtk_error_location \ "exprtk.hpp:" + details::to_str(__LINE__) \ - #if defined(__GNUC__) && (__GNUC__ >= 7) - - #define exprtk_disable_fallthrough_begin \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \ - - #define exprtk_disable_fallthrough_end \ - _Pragma ("GCC diagnostic pop") \ - - #else - #define exprtk_disable_fallthrough_begin (void)0; - #define exprtk_disable_fallthrough_end (void)0; - #endif - #if __cplusplus >= 201103L #define exprtk_override override #define exprtk_final final @@ -91,6 +77,18 @@ namespace exprtk #define exprtk_delete #endif + #if __cplusplus >= 201603L + #define exprtk_fallthrough [[fallthrough]]; + #elif __cplusplus >= 201103L + #define exprtk_fallthrough [[gnu::fallthrough]]; + #else + #ifndef _MSC_VER + #define exprtk_fallthrough __attribute__ ((fallthrough)); + #else + #define exprtk_fallthrough + #endif + #endif + namespace details { typedef char char_t; @@ -218,15 +216,15 @@ namespace exprtk { const std::size_t length = std::min(s1.size(),s2.size()); - for (std::size_t i = 0; i < length; ++i) + for (std::size_t i = 0; i < length; ++i) { const char_t c1 = static_cast(std::tolower(s1[i])); const char_t c2 = static_cast(std::tolower(s2[i])); - if (c1 > c2) - return false; - else if (c1 < c2) + if (c1 < c2) return true; + else if (c2 < c1) + return false; } return s1.size() < s2.size(); @@ -364,9 +362,9 @@ namespace exprtk } else if (parse_hex(itr1, end, *itr2)) { - itr1+= 4; - itr2+= 1; - removal_count +=4; + itr1 += 4; + itr2 += 1; + removal_count += 4; } else if ('a' == (*itr1)) { (*itr2++) = '\a'; ++itr1; ++removal_count; } else if ('b' == (*itr1)) { (*itr2++) = '\b'; ++itr1; ++removal_count; } @@ -381,6 +379,7 @@ namespace exprtk (*itr2++) = (*itr1++); ++removal_count; } + continue; } else @@ -432,85 +431,85 @@ namespace exprtk }; static const std::string reserved_words[] = - { - "break", "case", "continue", "default", "false", "for", - "if", "else", "ilike", "in", "like", "and", "nand", "nor", - "not", "null", "or", "repeat", "return", "shl", "shr", - "swap", "switch", "true", "until", "var", "while", "xnor", - "xor", "&", "|" - }; + { + "assert", "break", "case", "continue", "const", "default", + "false", "for", "if", "else", "ilike", "in", "like", "and", + "nand", "nor", "not", "null", "or", "repeat", "return", + "shl", "shr", "swap", "switch", "true", "until", "var", + "while", "xnor", "xor", "&", "|" + }; static const std::size_t reserved_words_size = sizeof(reserved_words) / sizeof(std::string); static const std::string reserved_symbols[] = - { - "abs", "acos", "acosh", "and", "asin", "asinh", "atan", - "atanh", "atan2", "avg", "break", "case", "ceil", "clamp", - "continue", "cos", "cosh", "cot", "csc", "default", - "deg2grad", "deg2rad", "equal", "erf", "erfc", "exp", - "expm1", "false", "floor", "for", "frac", "grad2deg", - "hypot", "iclamp", "if", "else", "ilike", "in", "inrange", - "like", "log", "log10", "log2", "logn", "log1p", "mand", - "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor", - "not", "not_equal", "null", "or", "pow", "rad2deg", - "repeat", "return", "root", "round", "roundn", "sec", "sgn", - "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap", - "switch", "tan", "tanh", "true", "trunc", "until", "var", - "while", "xnor", "xor", "&", "|" - }; + { + "abs", "acos", "acosh", "and", "asin", "asinh", "assert", + "atan", "atanh", "atan2", "avg", "break", "case", "ceil", + "clamp", "continue", "const", "cos", "cosh", "cot", "csc", + "default", "deg2grad", "deg2rad", "equal", "erf", "erfc", + "exp", "expm1", "false", "floor", "for", "frac", "grad2deg", + "hypot", "iclamp", "if", "else", "ilike", "in", "inrange", + "like", "log", "log10", "log2", "logn", "log1p", "mand", + "max", "min", "mod", "mor", "mul", "ncdf", "nand", "nor", + "not", "not_equal", "null", "or", "pow", "rad2deg", + "repeat", "return", "root", "round", "roundn", "sec", "sgn", + "shl", "shr", "sin", "sinc", "sinh", "sqrt", "sum", "swap", + "switch", "tan", "tanh", "true", "trunc", "until", "var", + "while", "xnor", "xor", "&", "|" + }; static const std::size_t reserved_symbols_size = sizeof(reserved_symbols) / sizeof(std::string); static const std::string base_function_list[] = - { - "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", - "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot", - "csc", "equal", "erf", "erfc", "exp", "expm1", "floor", - "frac", "hypot", "iclamp", "like", "log", "log10", "log2", - "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul", - "ncdf", "pow", "root", "round", "roundn", "sec", "sgn", - "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh", - "trunc", "not_equal", "inrange", "deg2grad", "deg2rad", - "rad2deg", "grad2deg" - }; + { + "abs", "acos", "acosh", "asin", "asinh", "atan", "atanh", + "atan2", "avg", "ceil", "clamp", "cos", "cosh", "cot", + "csc", "equal", "erf", "erfc", "exp", "expm1", "floor", + "frac", "hypot", "iclamp", "like", "log", "log10", "log2", + "logn", "log1p", "mand", "max", "min", "mod", "mor", "mul", + "ncdf", "pow", "root", "round", "roundn", "sec", "sgn", + "sin", "sinc", "sinh", "sqrt", "sum", "swap", "tan", "tanh", + "trunc", "not_equal", "inrange", "deg2grad", "deg2rad", + "rad2deg", "grad2deg" + }; static const std::size_t base_function_list_size = sizeof(base_function_list) / sizeof(std::string); static const std::string logic_ops_list[] = - { - "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|" - }; + { + "and", "nand", "nor", "not", "or", "xnor", "xor", "&", "|" + }; static const std::size_t logic_ops_list_size = sizeof(logic_ops_list) / sizeof(std::string); static const std::string cntrl_struct_list[] = - { - "if", "switch", "for", "while", "repeat", "return" - }; + { + "if", "switch", "for", "while", "repeat", "return" + }; static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string); static const std::string arithmetic_ops_list[] = - { - "+", "-", "*", "/", "%", "^" - }; + { + "+", "-", "*", "/", "%", "^" + }; static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string); static const std::string assignment_ops_list[] = - { - ":=", "+=", "-=", - "*=", "/=", "%=" - }; + { + ":=", "+=", "-=", + "*=", "/=", "%=" + }; static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string); static const std::string inequality_ops_list[] = - { - "<", "<=", "==", - "=", "!=", "<>", - ">=", ">" - }; + { + "<", "<=", "==", + "=", "!=", "<>", + ">=", ">" + }; static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string); @@ -646,7 +645,7 @@ namespace exprtk } } else if (data_end == d_itr) - return true; + break; if ((data_end == d_itr) || (null_itr == nd_itr)) return false; @@ -661,23 +660,27 @@ namespace exprtk inline bool wc_match(const std::string& wild_card, const std::string& str) { - return match_impl( + return match_impl + ( wild_card.data(), wild_card.data() + wild_card.size(), str.data(), str.data() + str.size(), - '*', '?'); + '*', '?' + ); } inline bool wc_imatch(const std::string& wild_card, const std::string& str) { - return match_impl( + return match_impl + ( wild_card.data(), wild_card.data() + wild_card.size(), str.data(), str.data() + str.size(), - '*', '?'); + '*', '?' + ); } inline bool sequence_match(const std::string& pattern, @@ -750,13 +753,55 @@ namespace exprtk ); } - static const double pow10[] = { - 1.0, - 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, - 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, - 1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012, - 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016 - }; + template + struct set_zero_value_impl + { + static inline void process(T* base_ptr, const std::size_t size) + { + const T zero = T(0); + for (std::size_t i = 0; i < size; ++i) + { + base_ptr[i] = zero; + } + } + }; + + #define pod_set_zero_value(T) \ + template <> \ + struct set_zero_value_impl \ + { \ + static inline void process(T* base_ptr, const std::size_t size) \ + { std::memset(base_ptr, 0x00, size * sizeof(T)); } \ + }; \ + + pod_set_zero_value(float ) + pod_set_zero_value(double ) + pod_set_zero_value(long double) + + #ifdef pod_set_zero_value + #undef pod_set_zero_value + #endif + + template + inline void set_zero_value(T* data, const std::size_t size) + { + set_zero_value_impl::process(data,size); + } + + template + inline void set_zero_value(std::vector& v) + { + set_zero_value(v.data(),v.size()); + } + + static const double pow10[] = + { + 1.0, + 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, + 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, + 1.0E+009, 1.0E+010, 1.0E+011, 1.0E+012, + 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016 + }; static const std::size_t pow10_size = sizeof(pow10) / sizeof(double); @@ -789,17 +834,17 @@ namespace exprtk number_type() {} }; - #define exprtk_register_real_type_tag(T) \ - template <> struct number_type \ - { typedef real_type_tag type; number_type() {} }; \ + #define exprtk_register_real_type_tag(T) \ + template <> struct number_type \ + { typedef real_type_tag type; number_type() {} }; \ - #define exprtk_register_int_type_tag(T) \ - template <> struct number_type \ - { typedef int_type_tag type; number_type() {} }; \ + #define exprtk_register_int_type_tag(T) \ + template <> struct number_type \ + { typedef int_type_tag type; number_type() {} }; \ + exprtk_register_real_type_tag(float ) exprtk_register_real_type_tag(double ) exprtk_register_real_type_tag(long double) - exprtk_register_real_type_tag(float ) exprtk_register_int_type_tag(short ) exprtk_register_int_type_tag(int ) @@ -848,6 +893,12 @@ namespace exprtk return static_cast<_int64_t>(v); } + template + inline _uint64_t to_uint64_impl(const T v, real_type_tag) + { + return static_cast<_uint64_t>(v); + } + template inline bool is_true_impl(const T v) { @@ -982,8 +1033,8 @@ namespace exprtk else return (T(-0.5) * v + T(1)) * v; } - else - return std::numeric_limits::quiet_NaN(); + + return std::numeric_limits::quiet_NaN(); } template @@ -993,8 +1044,8 @@ namespace exprtk { return std::log(T(1) + v); } - else - return std::numeric_limits::quiet_NaN(); + + return std::numeric_limits::quiet_NaN(); } template @@ -1193,9 +1244,9 @@ namespace exprtk #define exprtk_define_erf(TT, impl) \ inline TT erf_impl(const TT v) { return impl(v); } \ - exprtk_define_erf( float,::erff) - exprtk_define_erf( double,::erf ) - exprtk_define_erf(long double,::erfl) + exprtk_define_erf(float , ::erff) + exprtk_define_erf(double , ::erf ) + exprtk_define_erf(long double, ::erfl) #undef exprtk_define_erf #endif @@ -1204,13 +1255,14 @@ namespace exprtk { #if defined(_MSC_VER) && (_MSC_VER < 1900) // Credits: Abramowitz & Stegun Equations 7.1.25-28 - static const T c[] = { - T( 1.26551223), T(1.00002368), - T( 0.37409196), T(0.09678418), - T(-0.18628806), T(0.27886807), - T(-1.13520398), T(1.48851587), - T(-0.82215223), T(0.17087277) - }; + static const T c[] = + { + T( 1.26551223), T(1.00002368), + T( 0.37409196), T(0.09678418), + T(-0.18628806), T(0.27886807), + T(-1.13520398), T(1.48851587), + T(-0.82215223), T(0.17087277) + }; const T t = T(1) / (T(1) + T(0.5) * abs_impl(v,real_type_tag())); @@ -1262,10 +1314,7 @@ namespace exprtk template inline T ncdf_impl(const T v, real_type_tag) { - const T cnd = T(0.5) * (T(1) + - erf_impl(abs_impl(v,real_type_tag()) / - T(numeric::constant::sqrt2),real_type_tag())); - return (v < T(0)) ? (T(1) - cnd) : cnd; + return T(0.5) * erfc_impl(-(v / T(numeric::constant::sqrt2)),real_type_tag()); } template @@ -1289,12 +1338,47 @@ namespace exprtk return sinc_impl(static_cast(v),real_type_tag()); } + #if __cplusplus >= 201103L + template + inline T acosh_impl(const T v, real_type_tag) + { + return std::acosh(v); + } + + template + inline T asinh_impl(const T v, real_type_tag) + { + return std::asinh(v); + } + + template + inline T atanh_impl(const T v, real_type_tag) + { + return std::atanh(v); + } + #else + template + inline T acosh_impl(const T v, real_type_tag) + { + return std::log(v + std::sqrt((v * v) - T(1))); + } + + template + inline T asinh_impl(const T v, real_type_tag) + { + return std::log(v + std::sqrt((v * v) + T(1))); + } + + template + inline T atanh_impl(const T v, real_type_tag) + { + return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); + } + #endif + template inline T acos_impl(const T v, real_type_tag) { return std::acos (v); } - template inline T acosh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) - T(1))); } template inline T asin_impl(const T v, real_type_tag) { return std::asin (v); } - template inline T asinh_impl(const T v, real_type_tag) { return std::log(v + std::sqrt((v * v) + T(1))); } template inline T atan_impl(const T v, real_type_tag) { return std::atan (v); } - template inline T atanh_impl(const T v, real_type_tag) { return (std::log(T(1) + v) - std::log(T(1) - v)) / T(2); } template inline T ceil_impl(const T v, real_type_tag) { return std::ceil (v); } template inline T cos_impl(const T v, real_type_tag) { return std::cos (v); } template inline T cosh_impl(const T v, real_type_tag) { return std::cosh (v); } @@ -1390,6 +1474,13 @@ namespace exprtk return to_int64_impl(v, num_type); } + template + inline _uint64_t to_uint64(const T v) + { + const typename details::number_type::type num_type; + return to_uint64_impl(v, num_type); + } + template inline bool is_nan(const T v) { @@ -1629,38 +1720,38 @@ namespace exprtk { static const double fract10[] = { - 0.0, - 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010, - 1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020, - 1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030, - 1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040, - 1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050, - 1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060, - 1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070, - 1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080, - 1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090, - 1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100, - 1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110, - 1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120, - 1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130, - 1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140, - 1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150, - 1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160, - 1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170, - 1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180, - 1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190, - 1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200, - 1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210, - 1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220, - 1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230, - 1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240, - 1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250, - 1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260, - 1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270, - 1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280, - 1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290, - 1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300, - 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308 + 0.0, + 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010, + 1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020, + 1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030, + 1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040, + 1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050, + 1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060, + 1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070, + 1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080, + 1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090, + 1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100, + 1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110, + 1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120, + 1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130, + 1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140, + 1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150, + 1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160, + 1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170, + 1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180, + 1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190, + 1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200, + 1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210, + 1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220, + 1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230, + 1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240, + 1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250, + 1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260, + 1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270, + 1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280, + 1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290, + 1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300, + 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308 }; static const int fract10_size = static_cast(sizeof(fract10) / sizeof(double)); @@ -1710,7 +1801,6 @@ namespace exprtk if (length <= 4) { - exprtk_disable_fallthrough_begin switch (length) { #ifdef exprtk_use_lut @@ -1723,17 +1813,19 @@ namespace exprtk return_result = false; \ break; \ } \ + exprtk_fallthrough \ #else - #define exprtk_process_digit \ - if ((digit = (*itr++ - zero)) < 10) \ - result = result * T(10) + digit; \ - else \ - { \ - return_result = false; \ - break; \ - } \ + #define exprtk_process_digit \ + if ((digit = (*itr++ - zero)) < 10) \ + result = result * T(10) + digit; \ + else \ + { \ + return_result = false; \ + break; \ + } \ + exprtk_fallthrough \ #endif @@ -1748,7 +1840,6 @@ namespace exprtk #undef exprtk_process_digit } - exprtk_disable_fallthrough_end } else return_result = false; @@ -2067,14 +2158,74 @@ namespace exprtk virtual void handle_runtime_violation(const violation_context&) { - throw std::runtime_error("ExprTk Loop run-time violation."); + throw std::runtime_error("ExprTk Loop runtime violation."); } - virtual ~loop_runtime_check() {} + virtual ~loop_runtime_check() + {} }; typedef loop_runtime_check* loop_runtime_check_ptr; + struct vector_access_runtime_check + { + struct violation_context + { + void* base_ptr; + void* end_ptr; + void* access_ptr; + std::size_t type_size; + }; + + virtual ~vector_access_runtime_check() + {} + + virtual bool handle_runtime_violation(violation_context& /*context*/) + { + throw std::runtime_error("ExprTk runtime vector access violation."); + #if !defined(_MSC_VER) && !defined(__NVCOMPILER) + return false; + #endif + } + }; + + typedef vector_access_runtime_check* vector_access_runtime_check_ptr; + + struct assert_check + { + struct assert_context + { + std::string condition; + std::string message; + std::string id; + std::size_t offet; + }; + + virtual ~assert_check() + {} + + virtual void handle_assert(const assert_context& /*context*/) + { + } + }; + + typedef assert_check* assert_check_ptr; + + struct compilation_check + { + struct compilation_context + { + std::string error_message; + }; + + virtual bool continue_compilation(compilation_context& /*context*/) = 0; + + virtual ~compilation_check() + {} + }; + + typedef compilation_check* compilation_check_ptr; + namespace lexer { struct token @@ -2233,6 +2384,19 @@ namespace exprtk } } + static inline std::string seperator_to_str(const token_type t) + { + switch (t) + { + case e_comma : return ","; + case e_colon : return ":"; + case e_eof : return ";"; + default : return "UNKNOWN"; + } + + return "UNKNOWN"; + } + inline bool is_error() const { return ( @@ -2282,7 +2446,7 @@ namespace exprtk s_itr_ = str.data(); s_end_ = str.data() + str.size(); - eof_token_.set_operator(token_t::e_eof,s_end_,s_end_,base_itr_); + eof_token_.set_operator(token_t::e_eof, s_end_, s_end_, base_itr_); token_list_.clear(); while (!is_end(s_itr_)) @@ -2345,7 +2509,9 @@ namespace exprtk inline token_t& operator[](const std::size_t& index) { if (index < token_list_.size()) + { return token_list_[index]; + } else return eof_token_; } @@ -2353,7 +2519,9 @@ namespace exprtk inline token_t operator[](const std::size_t& index) const { if (index < token_list_.size()) + { return token_list_[index]; + } else return eof_token_; } @@ -2497,7 +2665,7 @@ namespace exprtk } } - ++s_itr_; + ++s_itr_; } if (2 == mode) @@ -2509,9 +2677,17 @@ namespace exprtk #endif } + inline bool next_is_digit(const details::char_cptr itr) const + { + return ((itr + 1) != s_end_) && + details::is_digit(*(itr + 1)); + } + inline void scan_token() { - if (details::is_whitespace(*s_itr_)) + const char_t c = *s_itr_; + + if (details::is_whitespace(c)) { skip_whitespace(); return; @@ -2521,34 +2697,39 @@ namespace exprtk skip_comments(); return; } - else if (details::is_operator_char(*s_itr_)) + else if (details::is_operator_char(c)) { scan_operator(); return; } - else if (details::is_letter(*s_itr_)) + else if (details::is_letter(c)) { scan_symbol(); return; } - else if (details::is_digit((*s_itr_)) || ('.' == (*s_itr_))) + else if (('.' == c) && !next_is_digit(s_itr_)) + { + scan_operator(); + return; + } + else if (details::is_digit(c) || ('.' == c)) { scan_number(); return; } - else if ('$' == (*s_itr_)) + else if ('$' == c) { scan_special_function(); return; } #ifndef exprtk_disable_string_capabilities - else if ('\'' == (*s_itr_)) + else if ('\'' == c) { scan_string(); return; } #endif - else if ('~' == (*s_itr_)) + else if ('~' == c) { token_t t; t.set_symbol(s_itr_, s_itr_ + 1, base_itr_); @@ -2658,7 +2839,7 @@ namespace exprtk } token_t t; - t.set_symbol(initial_itr,s_itr_,base_itr_); + t.set_symbol(initial_itr, s_itr_, base_itr_); token_list_.push_back(t); } @@ -2858,12 +3039,12 @@ namespace exprtk ((s_itr_ + 4) <= s_end_) ) { - const bool x_seperator = ('X' == std::toupper(*(s_itr_ + 1))); + const bool x_separator = ('X' == std::toupper(*(s_itr_ + 1))); const bool both_digits = details::is_hex_digit(*(s_itr_ + 2)) && details::is_hex_digit(*(s_itr_ + 3)) ; - if (!(x_seperator && both_digits)) + if (!(x_separator && both_digits)) { t.set_error(token::e_err_string, initial_itr, s_itr_, base_itr_); token_list_.push_back(t); @@ -2903,8 +3084,8 @@ namespace exprtk } t.set_string( - parsed_string, - static_cast(std::distance(base_itr_,initial_itr))); + parsed_string, + static_cast(std::distance(base_itr_,initial_itr))); } token_list_.push_back(t); @@ -2945,7 +3126,8 @@ namespace exprtk { public: - virtual ~token_scanner() {} + virtual ~token_scanner() + {} explicit token_scanner(const std::size_t& stride) : stride_(stride) @@ -2972,7 +3154,7 @@ namespace exprtk if (!operator()(t0)) { - return i; + return 0; } } break; @@ -2984,7 +3166,7 @@ namespace exprtk if (!operator()(t0, t1)) { - return i; + return 0; } } break; @@ -2997,7 +3179,7 @@ namespace exprtk if (!operator()(t0, t1, t2)) { - return i; + return 0; } } break; @@ -3011,7 +3193,7 @@ namespace exprtk if (!operator()(t0, t1, t2, t3)) { - return i; + return 0; } } break; @@ -3019,7 +3201,7 @@ namespace exprtk } } - return (g.token_list_.size() - stride_ + 1); + return 0; } virtual bool operator() (const token&) @@ -3211,7 +3393,7 @@ namespace exprtk generator::token_list_t token_list; token_list.reserve(10000); - for (int i = 0; i < static_cast(g.token_list_.size() - 1); ++i) + for (int i = 0; i < static_cast(g.token_list_.size() - 1); ++i) { token t; @@ -3227,7 +3409,7 @@ namespace exprtk ++changes; - i+=2; + i += 2; if (static_cast(i) >= (g.token_list_.size() - 1)) break; @@ -3253,7 +3435,7 @@ namespace exprtk generator::token_list_t token_list; token_list.reserve(10000); - for (int i = 0; i < static_cast(g.token_list_.size() - 2); ++i) + for (int i = 0; i < static_cast(g.token_list_.size() - 2); ++i) { token t; @@ -3269,7 +3451,7 @@ namespace exprtk ++changes; - i+=3; + i += 3; if (static_cast(i) >= (g.token_list_.size() - 2)) break; @@ -3367,7 +3549,7 @@ namespace exprtk std::set ignore_set_; }; - class operator_joiner : public token_joiner + class operator_joiner exprtk_final : public token_joiner { public: @@ -3543,7 +3725,7 @@ namespace exprtk } }; - class bracket_checker : public lexer::token_scanner + class bracket_checker exprtk_final : public lexer::token_scanner { public: @@ -3554,7 +3736,7 @@ namespace exprtk , state_(true) {} - bool result() + bool result() exprtk_override { if (!stack_.empty()) { @@ -3575,7 +3757,7 @@ namespace exprtk return error_token_; } - void reset() + void reset() exprtk_override { // Why? because msvc doesn't support swap properly. stack_ = std::stack >(); @@ -3583,7 +3765,7 @@ namespace exprtk error_token_.clear(); } - bool operator() (const lexer::token& t) + bool operator() (const lexer::token& t) exprtk_override { if ( !t.value.empty() && @@ -3640,18 +3822,18 @@ namespace exprtk , current_index_(0) {} - bool result() + bool result() exprtk_override { return error_list_.empty(); } - void reset() + void reset() exprtk_override { error_list_.clear(); current_index_ = 0; } - bool operator() (const lexer::token& t) + bool operator() (const lexer::token& t) exprtk_override { if (token::e_number == t.type) { @@ -3692,7 +3874,7 @@ namespace exprtk std::vector error_list_; }; - class symbol_replacer : public lexer::token_modifier + class symbol_replacer exprtk_final : public lexer::token_modifier { private: @@ -3735,7 +3917,7 @@ namespace exprtk private: - bool modify(lexer::token& t) + bool modify(lexer::token& t) exprtk_override { if (lexer::token::e_symbol == t.type) { @@ -3798,12 +3980,12 @@ namespace exprtk add_invalid_set1(lexer::token::e_ternary); } - bool result() + bool result() exprtk_override { return error_list_.empty(); } - bool operator() (const lexer::token& t0, const lexer::token& t1) + bool operator() (const lexer::token& t0, const lexer::token& t1) exprtk_override { const set_t::value_type p = std::make_pair(t0.type,t1.type); @@ -3965,12 +4147,12 @@ namespace exprtk add_invalid(lexer::token::e_pow , lexer::token::e_mod , lexer::token::e_pow ); } - bool result() + bool result() exprtk_override { return error_list_.empty(); } - bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2) + bool operator() (const lexer::token& t0, const lexer::token& t1, const lexer::token& t2) exprtk_override { const set_t::value_type p = std::make_pair(t0.type,std::make_pair(t1.type,t2.type)); @@ -4227,6 +4409,11 @@ namespace exprtk return current_token_; } + inline const token_t& peek_next_token() + { + return lexer_.peek_next_token(); + } + enum token_advance_mode { e_hold = 0, @@ -4270,6 +4457,110 @@ namespace exprtk return true; } + inline bool token_is(const std::string& value, + const token_advance_mode mode = e_advance) + { + if (!exprtk::details::imatch(value,current_token().value)) + { + return false; + } + + advance_token(mode); + + return true; + } + + inline bool token_is_arithmetic_opr(const token_advance_mode mode = e_advance) + { + switch (current_token().type) + { + case token_t::e_add : + case token_t::e_sub : + case token_t::e_div : + case token_t::e_mul : + case token_t::e_mod : + case token_t::e_pow : break; + default : return false; + } + + advance_token(mode); + + return true; + } + + inline bool token_is_ineq_opr(const token_advance_mode mode = e_advance) + { + switch (current_token().type) + { + case token_t::e_eq : + case token_t::e_lte : + case token_t::e_ne : + case token_t::e_gte : + case token_t::e_lt : + case token_t::e_gt : break; + default : return false; + } + + advance_token(mode); + + return true; + } + + inline bool token_is_left_bracket(const token_advance_mode mode = e_advance) + { + switch (current_token().type) + { + case token_t::e_lbracket : + case token_t::e_lcrlbracket : + case token_t::e_lsqrbracket : break; + default : return false; + } + + advance_token(mode); + + return true; + } + + inline bool token_is_right_bracket(const token_advance_mode mode = e_advance) + { + switch (current_token().type) + { + case token_t::e_rbracket : + case token_t::e_rcrlbracket : + case token_t::e_rsqrbracket : break; + default : return false; + } + + advance_token(mode); + + return true; + } + + inline bool token_is_bracket(const token_advance_mode mode = e_advance) + { + switch (current_token().type) + { + case token_t::e_rbracket : + case token_t::e_rcrlbracket : + case token_t::e_rsqrbracket : + case token_t::e_lbracket : + case token_t::e_lcrlbracket : + case token_t::e_lsqrbracket : break; + default : return false; + } + + advance_token(mode); + + return true; + } + + inline bool token_is_loop(const token_advance_mode mode = e_advance) + { + return token_is("for" , mode) || + token_is("while" , mode) || + token_is("repeat", mode) ; + } + inline bool peek_token_is(const token_t::token_type& ttype) { return (lexer_.peek_next_token().type == ttype); @@ -4296,16 +4587,22 @@ namespace exprtk typedef T* data_ptr_t; vector_view(data_ptr_t data, const std::size_t& size) - : size_(size) + : base_size_(size) + , size_(size) , data_(data) , data_ref_(0) - {} + { + assert(size_ > 0); + } vector_view(const vector_view& vv) - : size_(vv.size_) + : base_size_(vv.base_size_) + , size_(vv.size_) , data_(vv.data_) , data_ref_(0) - {} + { + assert(size_ > 0); + } inline void rebase(data_ptr_t data) { @@ -4325,6 +4622,11 @@ namespace exprtk return data_; } + inline std::size_t base_size() const + { + return base_size_; + } + inline std::size_t size() const { return size_; @@ -4332,22 +4634,55 @@ namespace exprtk inline const T& operator[](const std::size_t index) const { + assert(index < size_); return data_[index]; } inline T& operator[](const std::size_t index) { + assert(index < size_); return data_[index]; } void set_ref(data_ptr_t* data_ref) { data_ref_.push_back(data_ref); + exprtk_debug(("vector_view::set_ref() - data_ref: %p data_ref_.size(): %d\n", + reinterpret_cast(data_ref), + static_cast(data_ref_.size()))); + } + + void remove_ref(data_ptr_t* data_ref) + { + data_ref_.erase( + std::remove(data_ref_.begin(), data_ref_.end(), data_ref), + data_ref_.end()); + exprtk_debug(("vector_view::remove_ref() - data_ref: %p data_ref_.size(): %d\n", + reinterpret_cast(data_ref), + static_cast(data_ref_.size()))); + } + + bool set_size(const std::size_t new_size) + { + if ((new_size > 0) && (new_size <= base_size_)) + { + size_ = new_size; + exprtk_debug(("vector_view::set_size() - data_: %p size: %lu\n", + reinterpret_cast(data_), + size_)); + return true; + } + + exprtk_debug(("vector_view::set_size() - error invalid new_size: %lu base_size: %lu\n", + new_size, + base_size_)); + return false; } private: - const std::size_t size_; + const std::size_t base_size_; + std::size_t size_; data_ptr_t data_; std::vector data_ref_; }; @@ -4523,6 +4858,16 @@ namespace exprtk return v_; } + inline operator value_t() const + { + return v_; + } + + inline operator value_t() + { + return v_; + } + template inline bool to_int(IntType& i) const { @@ -4571,6 +4916,9 @@ namespace exprtk public: typedef type_store type_store_t; + typedef typename type_store_t::scalar_view scalar_t; + typedef typename type_store_t::vector_view vector_t; + typedef typename type_store_t::string_view string_t; results_context() : results_available_(false) @@ -4594,6 +4942,61 @@ namespace exprtk return parameter_list_[index]; } + inline bool get_scalar(const std::size_t& index, T& out) const + { + if ( + (index < parameter_list_.size()) && + (parameter_list_[index].type == type_store_t::e_scalar) + ) + { + const scalar_t scalar(parameter_list_[index]); + out = scalar(); + return true; + } + + return false; + } + + template + inline bool get_vector(const std::size_t& index, OutputIterator out_itr) const + { + if ( + (index < parameter_list_.size()) && + (parameter_list_[index].type == type_store_t::e_vector) + ) + { + const vector_t vector(parameter_list_[index]); + for (std::size_t i = 0; i < vector.size(); ++i) + { + *(out_itr++) = vector[i]; + } + + return true; + } + + return false; + } + + inline bool get_vector(const std::size_t& index, std::vector& out) const + { + return get_vector(index,std::back_inserter(out)); + } + + inline bool get_string(const std::size_t& index, std::string& out) const + { + if ( + (index < parameter_list_.size()) && + (parameter_list_[index].type == type_store_t::e_string) + ) + { + const string_t str(parameter_list_[index]); + out.assign(str.begin(),str.size()); + return true; + } + + return false; + } + private: inline void clear() @@ -4740,10 +5143,11 @@ namespace exprtk namespace loop_unroll { + const unsigned int global_loop_batch_size = #ifndef exprtk_disable_superscalar_unroll - const unsigned int global_loop_batch_size = 16; + 16; #else - const unsigned int global_loop_batch_size = 4; + 4; #endif struct details @@ -4770,11 +5174,28 @@ namespace exprtk ptr, static_cast(size))); else - exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr)); + exprtk_debug(("%s - addr: %p\n", s.c_str(), ptr)); + } + + template + inline void dump_vector(const std::string& vec_name, const T* data, const std::size_t size) + { + printf("----- %s (%p) -----\n", + vec_name.c_str(), + static_cast(data)); + printf("[ "); + for (std::size_t i = 0; i < size; ++i) + { + printf("%8.3f\t", data[i]); + } + printf(" ]\n"); + printf("---------------------\n"); } #else inline void dump_ptr(const std::string&, const void*) {} inline void dump_ptr(const std::string&, const void*, const std::size_t) {} + template + inline void dump_vector(const std::string&, const T*, const std::size_t) {} #endif template @@ -4897,7 +5318,7 @@ namespace exprtk { if (this != &vds) { - std::size_t final_size = min_size(control_block_, vds.control_block_); + const std::size_t final_size = min_size(control_block_, vds.control_block_); vds.control_block_->size = final_size; control_block_->size = final_size; @@ -4947,7 +5368,7 @@ namespace exprtk if (5 == i) exprtk_debug(("\n")); - exprtk_debug(("%15.10f ",data()[i])); + exprtk_debug(("%15.10f ", data()[i])); } exprtk_debug(("\n")); #endif @@ -5060,8 +5481,8 @@ namespace exprtk case e_xnor : return xnor_opr(arg0,arg1); case e_root : return root (arg0,arg1); case e_roundn : return roundn (arg0,arg1); - case e_equal : return equal (arg0,arg1); - case e_nequal : return nequal (arg0,arg1); + case e_equal : return equal (arg0,arg1); + case e_nequal : return nequal (arg0,arg1); case e_hypot : return hypot (arg0,arg1); case e_shr : return shr (arg0,arg1); case e_shl : return shl (arg0,arg1); @@ -5130,17 +5551,19 @@ namespace exprtk typedef Node** node_pp_t; typedef std::vector noderef_list_t; - virtual ~node_collector_interface() {} + virtual ~node_collector_interface() + {} - virtual void collect_nodes(noderef_list_t&) {} + virtual void collect_nodes(noderef_list_t&) + {} }; template struct node_depth_base; template - class expression_node : public node_collector_interface >, - public node_depth_base > + class expression_node : public node_collector_interface > + , public node_depth_base > { public: @@ -5177,12 +5600,14 @@ namespace exprtk e_vovovoc , e_vovocov , e_vocovov , e_covovov , e_covocov , e_vocovoc , e_covovoc , e_vococov , e_sf3ext , e_sf4ext , e_nulleq , e_strass , - e_vector , e_vecelem , e_rbvecelem , e_rbveccelem , - e_vecdefass , e_vecvalass , e_vecvecass , e_vecopvalass , - e_vecopvecass , e_vecfunc , e_vecvecswap , e_vecvecineq , - e_vecvalineq , e_valvecineq , e_vecvecarith , e_vecvalarith , - e_valvecarith , e_vecunaryop , e_vecondition , e_break , - e_continue , e_swap + e_vector , e_vecsize , e_vecelem , e_veccelem , + e_vecelemrtc , e_veccelemrtc , e_rbvecelem , e_rbvecelemrtc , + e_rbveccelem , e_rbveccelemrtc , e_vecinit , e_vecvalass , + e_vecvecass , e_vecopvalass , e_vecopvecass , e_vecfunc , + e_vecvecswap , e_vecvecineq , e_vecvalineq , e_valvecineq , + e_vecvecarith , e_vecvalarith , e_valvecarith , e_vecunaryop , + e_vecondition , e_break , e_continue , e_swap , + e_assert }; typedef T value_type; @@ -5191,7 +5616,8 @@ namespace exprtk typedef typename nci_t::noderef_list_t noderef_list_t; typedef node_depth_base > ndb_t; - virtual ~expression_node() {} + virtual ~expression_node() + {} inline virtual T value() const { @@ -5207,6 +5633,11 @@ namespace exprtk { return e_none; } + + inline virtual bool valid() const + { + return true; + } }; // class expression_node template @@ -5251,6 +5682,12 @@ namespace exprtk return std::equal_to()(T(0),node.first->value()); } + template + inline bool is_literal_node(const expression_node* node) + { + return node && (details::expression_node::e_constant == node->type()); + } + template inline bool is_unary_node(const expression_node* node) { @@ -5280,10 +5717,15 @@ namespace exprtk { return node && ( - details::expression_node::e_variable == node->type() || - details::expression_node::e_vecelem == node->type() || - details::expression_node::e_rbvecelem == node->type() || - details::expression_node::e_rbveccelem == node->type() + details::expression_node::e_variable == node->type() || + details::expression_node::e_vecelem == node->type() || + details::expression_node::e_veccelem == node->type() || + details::expression_node::e_vecelemrtc == node->type() || + details::expression_node::e_veccelemrtc == node->type() || + details::expression_node::e_rbvecelem == node->type() || + details::expression_node::e_rbveccelem == node->type() || + details::expression_node::e_rbvecelemrtc == node->type() || + details::expression_node::e_rbveccelemrtc == node->type() ); } @@ -5293,12 +5735,42 @@ namespace exprtk return node && (details::expression_node::e_vecelem == node->type()); } + template + inline bool is_vector_celem_node(const expression_node* node) + { + return node && (details::expression_node::e_veccelem == node->type()); + } + + template + inline bool is_vector_elem_rtc_node(const expression_node* node) + { + return node && (details::expression_node::e_vecelemrtc == node->type()); + } + + template + inline bool is_vector_celem_rtc_node(const expression_node* node) + { + return node && (details::expression_node::e_veccelemrtc == node->type()); + } + template inline bool is_rebasevector_elem_node(const expression_node* node) { return node && (details::expression_node::e_rbvecelem == node->type()); } + template + inline bool is_rebasevector_elem_rtc_node(const expression_node* node) + { + return node && (details::expression_node::e_rbvecelemrtc == node->type()); + } + + template + inline bool is_rebasevector_celem_rtc_node(const expression_node* node) + { + return node && (details::expression_node::e_rbveccelemrtc == node->type()); + } + template inline bool is_rebasevector_celem_node(const expression_node* node) { @@ -5376,6 +5848,12 @@ namespace exprtk return node && (details::expression_node::e_function == node->type()); } + template + inline bool is_vararg_node(const expression_node* node) + { + return node && (details::expression_node::e_vararg == node->type()); + } + template inline bool is_return_node(const expression_node* node) { @@ -5396,7 +5874,13 @@ namespace exprtk } template - inline bool branch_deletable(expression_node* node) + inline bool is_assert_node(const expression_node* node) + { + return node && (details::expression_node::e_assert == node->type()); + } + + template + inline bool branch_deletable(const expression_node* node) { return (0 != node) && !is_variable_node(node) && @@ -5404,7 +5888,7 @@ namespace exprtk } template - inline bool all_nodes_valid(expression_node* (&b)[N]) + inline bool all_nodes_valid(expression_node* const (&b)[N]) { for (std::size_t i = 0; i < N; ++i) { @@ -5428,7 +5912,7 @@ namespace exprtk } template - inline bool all_nodes_variables(expression_node* (&b)[N]) + inline bool all_nodes_variables(expression_node* const (&b)[N]) { for (std::size_t i = 0; i < N; ++i) { @@ -5444,7 +5928,7 @@ namespace exprtk template class Sequence> - inline bool all_nodes_variables(Sequence*,Allocator>& b) + inline bool all_nodes_variables(const Sequence*,Allocator>& b) { for (std::size_t i = 0; i < b.size(); ++i) { @@ -5478,7 +5962,7 @@ namespace exprtk for (std::size_t i = 0; i < node_delete_list.size(); ++i) { node_ptr_t& node = *node_delete_list[i]; - exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", static_cast(node))); + exprtk_debug(("ncd::delete_nodes() - deleting: %p\n", reinterpret_cast(node))); delete node; node = reinterpret_cast(0); } @@ -5583,7 +6067,8 @@ namespace exprtk , depth(0) {} - virtual ~node_depth_base() {} + virtual ~node_depth_base() + {} virtual std::size_t node_depth() const { return 1; } @@ -5615,6 +6100,7 @@ namespace exprtk if (!depth_set) { depth = 0; + for (std::size_t i = 0; i < N; ++i) { if (branch[i].first) @@ -5622,6 +6108,7 @@ namespace exprtk depth = std::max(depth,branch[i].first->node_depth()); } } + depth += 1; depth_set = true; } @@ -5629,12 +6116,34 @@ namespace exprtk return depth; } + template + std::size_t max_node_depth(const BranchType& n0, const BranchType& n1) const + { + return std::max(compute_node_depth(n0), compute_node_depth(n1)); + } + + template + std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, const BranchType& n2) const + { + return std::max(compute_node_depth(n0), + std::max(compute_node_depth(n1), compute_node_depth(n2))); + } + + template + std::size_t max_node_depth(const BranchType& n0, const BranchType& n1, + const BranchType& n2, const BranchType& n3) const + { + return std::max( + std::max(compute_node_depth(n0), compute_node_depth(n1)), + std::max(compute_node_depth(n2), compute_node_depth(n3))); + } + template std::size_t compute_node_depth(const BranchType& n0, const BranchType& n1) const { if (!depth_set) { - depth = 1 + std::max(compute_node_depth(n0), compute_node_depth(n1)); + depth = 1 + max_node_depth(n0, n1); depth_set = true; } @@ -5647,9 +6156,7 @@ namespace exprtk { if (!depth_set) { - depth = 1 + std::max( - std::max(compute_node_depth(n0), compute_node_depth(n1)), - compute_node_depth(n2)); + depth = 1 + max_node_depth(n0, n1, n2); depth_set = true; } @@ -5662,9 +6169,7 @@ namespace exprtk { if (!depth_set) { - depth = 1 + std::max( - std::max(compute_node_depth(n0), compute_node_depth(n1)), - std::max(compute_node_depth(n2), compute_node_depth(n3))); + depth = 1 + max_node_depth(n0, n1, n2, n3); depth_set = true; } @@ -5684,6 +6189,7 @@ namespace exprtk depth = std::max(depth, compute_node_depth(branch_list[i])); } } + depth_set = true; } @@ -5703,6 +6209,7 @@ namespace exprtk depth = std::max(depth, compute_node_depth(branch_list[i].first)); } } + depth_set = true; } @@ -5795,12 +6302,14 @@ namespace exprtk typedef Type value_type; typedef value_type* value_ptr; typedef const value_ptr const_value_ptr; + typedef vector_holder vector_holder_t; class vector_holder_base { public: - virtual ~vector_holder_base() {} + virtual ~vector_holder_base() + {} inline value_ptr operator[](const std::size_t& index) const { @@ -5812,6 +6321,11 @@ namespace exprtk return vector_size(); } + inline std::size_t base_size() const + { + return vector_base_size(); + } + inline value_ptr data() const { return value_at(0); @@ -5822,15 +6336,25 @@ namespace exprtk return false; } - virtual void set_ref(value_ptr*) {} + virtual void set_ref(value_ptr*) + {} + + virtual void remove_ref(value_ptr*) + {} + + virtual vector_view* rebaseable_instance() + { + return reinterpret_cast*>(0); + } protected: virtual value_ptr value_at(const std::size_t&) const = 0; virtual std::size_t vector_size() const = 0; + virtual std::size_t vector_base_size() const = 0; }; - class array_vector_impl : public vector_holder_base + class array_vector_impl exprtk_final : public vector_holder_base { public: @@ -5841,19 +6365,22 @@ namespace exprtk protected: - value_ptr value_at(const std::size_t& index) const + value_ptr value_at(const std::size_t& index) const exprtk_override { - if (index < size_) - return const_cast(vec_ + index); - else - return const_value_ptr(0); + assert(index < size_); + return const_cast(vec_ + index); } - std::size_t vector_size() const + std::size_t vector_size() const exprtk_override { return size_; } + std::size_t vector_base_size() const exprtk_override + { + return vector_size(); + } + private: array_vector_impl(const array_vector_impl&) exprtk_delete; @@ -5865,28 +6392,34 @@ namespace exprtk template class Sequence> - class sequence_vector_impl : public vector_holder_base + class sequence_vector_impl exprtk_final : public vector_holder_base { public: typedef Sequence sequence_t; - sequence_vector_impl(sequence_t& seq) + explicit sequence_vector_impl(sequence_t& seq) : sequence_(seq) {} protected: - value_ptr value_at(const std::size_t& index) const + value_ptr value_at(const std::size_t& index) const exprtk_override { - return (index < sequence_.size()) ? (&sequence_[index]) : const_value_ptr(0); + assert(index < sequence_.size()); + return (&sequence_[index]); } - std::size_t vector_size() const + std::size_t vector_size() const exprtk_override { return sequence_.size(); } + std::size_t vector_base_size() const exprtk_override + { + return vector_size(); + } + private: sequence_vector_impl(const sequence_vector_impl&) exprtk_delete; @@ -5895,7 +6428,7 @@ namespace exprtk sequence_t& sequence_; }; - class vector_view_impl : public vector_holder_base + class vector_view_impl exprtk_final : public vector_holder_base { public: @@ -5903,30 +6436,48 @@ namespace exprtk vector_view_impl(vector_view_t& vec_view) : vec_view_(vec_view) - {} + { + assert(vec_view_.size() > 0); + } - void set_ref(value_ptr* ref) + void set_ref(value_ptr* ref) exprtk_override { vec_view_.set_ref(ref); } - virtual inline bool rebaseable() const + void remove_ref(value_ptr* ref) exprtk_override + { + vec_view_.remove_ref(ref); + } + + bool rebaseable() const exprtk_override { return true; } + vector_view* rebaseable_instance() exprtk_override + { + return &vec_view_; + } + protected: - value_ptr value_at(const std::size_t& index) const + value_ptr value_at(const std::size_t& index) const exprtk_override { - return (index < vec_view_.size()) ? (&vec_view_[index]) : const_value_ptr(0); + assert(index < vec_view_.size()); + return (&vec_view_[index]); } - std::size_t vector_size() const + std::size_t vector_size() const exprtk_override { return vec_view_.size(); } + std::size_t vector_base_size() const exprtk_override + { + return vec_view_.base_size(); + } + private: vector_view_impl(const vector_view_impl&) exprtk_delete; @@ -5935,6 +6486,62 @@ namespace exprtk vector_view_t& vec_view_; }; + class resizable_vector_impl exprtk_final : public vector_holder_base + { + public: + + resizable_vector_impl(vector_holder& vec_view_holder, + const Type* vec, + const std::size_t& vec_size) + : vec_(vec) + , size_(vec_size) + , vec_view_holder_(*vec_view_holder.rebaseable_instance()) + { + assert(vec_view_holder.rebaseable_instance()); + assert(size_ <= vector_base_size()); + } + + virtual ~resizable_vector_impl() + {} + + protected: + + value_ptr value_at(const std::size_t& index) const exprtk_override + { + assert(index < vector_size()); + return const_cast(vec_ + index); + } + + std::size_t vector_size() const exprtk_override + { + return vec_view_holder_.size(); + } + + std::size_t vector_base_size() const exprtk_override + { + return vec_view_holder_.base_size(); + } + + bool rebaseable() const exprtk_override + { + return true; + } + + virtual vector_view* rebaseable_instance() exprtk_override + { + return &vec_view_holder_; + } + + private: + + resizable_vector_impl(const resizable_vector_impl&) exprtk_delete; + resizable_vector_impl& operator=(const resizable_vector_impl&) exprtk_delete; + + const Type* vec_; + const std::size_t size_; + vector_view& vec_view_holder_; + }; + public: typedef typename details::vec_data_store vds_t; @@ -5956,6 +6563,10 @@ namespace exprtk : vector_holder_base_(new(buffer)vector_view_impl(vec)) {} + explicit vector_holder(vector_holder_t& vec_holder, const vds_t& vds) + : vector_holder_base_(new(buffer)resizable_vector_impl(vec_holder, vds.data(), vds.size())) + {} + inline value_ptr operator[](const std::size_t& index) const { return (*vector_holder_base_)[index]; @@ -5966,6 +6577,11 @@ namespace exprtk return vector_holder_base_->size(); } + inline std::size_t base_size() const + { + return vector_holder_base_->base_size(); + } + inline value_ptr data() const { return vector_holder_base_->data(); @@ -5973,7 +6589,18 @@ namespace exprtk void set_ref(value_ptr* ref) { - vector_holder_base_->set_ref(ref); + if (rebaseable()) + { + vector_holder_base_->set_ref(ref); + } + } + + void remove_ref(value_ptr* ref) + { + if (rebaseable()) + { + vector_holder_base_->remove_ref(ref); + } } bool rebaseable() const @@ -5981,8 +6608,16 @@ namespace exprtk return vector_holder_base_->rebaseable(); } + vector_view* rebaseable_instance() + { + return vector_holder_base_->rebaseable_instance(); + } + private: + vector_holder(const vector_holder&) exprtk_delete; + vector_holder& operator=(const vector_holder&) exprtk_delete; + mutable vector_holder_base* vector_holder_base_; uchar_t buffer[64]; }; @@ -6060,12 +6695,11 @@ namespace exprtk : equality_(equality) { construct_branch_pair(branch_, branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); - const T v = branch_.first->value(); const bool result = details::numeric::is_nan(v); @@ -6085,6 +6719,11 @@ namespace exprtk return branch_.first; } + inline bool valid() const exprtk_override + { + return branch_.first; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(branch_, node_delete_list); @@ -6146,7 +6785,8 @@ namespace exprtk typedef range_pack range_t; - virtual ~range_interface() {} + virtual ~range_interface() + {} virtual range_t& range_ref() = 0; @@ -6161,7 +6801,8 @@ namespace exprtk typedef range_data_type range_data_type_t; - virtual ~string_base_node() {} + virtual ~string_base_node() + {} virtual std::string str () const = 0; @@ -6172,9 +6813,9 @@ namespace exprtk template class string_literal_node exprtk_final - : public expression_node , - public string_base_node, - public range_interface + : public expression_node + , public string_base_node + , public range_interface { public: @@ -6183,8 +6824,8 @@ namespace exprtk explicit string_literal_node(const std::string& v) : value_(v) { - rp_.n0_c = std::make_pair(true,0); - rp_.n1_c = std::make_pair(true,v.size() - 1); + rp_.n0_c = std::make_pair(true, 0); + rp_.n1_c = std::make_pair(true, v.size()); rp_.cache.first = rp_.n0_c.second; rp_.cache.second = rp_.n1_c.second; } @@ -6251,13 +6892,13 @@ namespace exprtk : operation_(opr) { construct_branch_pair(branch_,branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); - const T arg = branch_.first->value(); - return numeric::process(operation_,arg); + return numeric::process + (operation_,branch_.first->value()); } inline typename expression_node::node_type type() const exprtk_override @@ -6275,6 +6916,11 @@ namespace exprtk return branch_.first; } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + inline void release() { branch_.second = false; @@ -6310,17 +6956,17 @@ namespace exprtk : operation_(opr) { init_branches<2>(branch_, branch0, branch1); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_[0].first); - assert(branch_[1].first); - - const T arg0 = branch_[0].first->value(); - const T arg1 = branch_[1].first->value(); - - return numeric::process(operation_, arg0, arg1); + return numeric::process + ( + operation_, + branch_[0].first->value(), + branch_[1].first->value() + ); } inline typename expression_node::node_type type() const exprtk_override @@ -6335,17 +6981,20 @@ namespace exprtk inline expression_node* branch(const std::size_t& index = 0) const exprtk_override { - if (0 == index) - return branch_[0].first; - else if (1 == index) - return branch_[1].first; - else - return reinterpret_cast(0); + assert(index < 2); + return branch_[index].first; + } + + inline bool valid() const exprtk_override + { + return + branch_[0].first && branch_[0].first->valid() && + branch_[1].first && branch_[1].first->valid() ; } void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_final @@ -6370,16 +7019,13 @@ namespace exprtk binary_ext_node(expression_ptr branch0, expression_ptr branch1) { init_branches<2>(branch_, branch0, branch1); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_[0].first); - assert(branch_[1].first); - const T arg0 = branch_[0].first->value(); const T arg1 = branch_[1].first->value(); - return Operation::process(arg0,arg1); } @@ -6395,17 +7041,20 @@ namespace exprtk inline expression_node* branch(const std::size_t& index = 0) const exprtk_override { - if (0 == index) - return branch_[0].first; - else if (1 == index) - return branch_[1].first; - else - return reinterpret_cast(0); + assert(index < 2); + return branch_[index].first; + } + + inline bool valid() const exprtk_override + { + return + branch_[0].first && branch_[0].first->valid() && + branch_[1].first && branch_[1].first->valid() ; } void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override @@ -6433,14 +7082,11 @@ namespace exprtk : operation_(opr) { init_branches<3>(branch_, branch0, branch1, branch2); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_[0].first); - assert(branch_[1].first); - assert(branch_[2].first); - const T arg0 = branch_[0].first->value(); const T arg1 = branch_[1].first->value(); const T arg2 = branch_[2].first->value(); @@ -6466,9 +7112,17 @@ namespace exprtk return expression_node::e_trinary; } + inline bool valid() const exprtk_override + { + return + branch_[0].first && branch_[0].first->valid() && + branch_[1].first && branch_[1].first->valid() && + branch_[2].first && branch_[2].first->valid() ; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override exprtk_final @@ -6512,7 +7166,7 @@ namespace exprtk void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override exprtk_final @@ -6520,6 +7174,15 @@ namespace exprtk return expression_node::ndb_t::template compute_node_depth<4>(branch_); } + inline bool valid() const exprtk_override + { + return + branch_[0].first && branch_[0].first->valid() && + branch_[1].first && branch_[1].first->valid() && + branch_[2].first && branch_[2].first->valid() && + branch_[3].first && branch_[3].first->valid() ; + } + protected: operator_type operation_; @@ -6541,14 +7204,11 @@ namespace exprtk construct_branch_pair(condition_ , condition ); construct_branch_pair(consequent_ , consequent ); construct_branch_pair(alternative_, alternative); + assert(valid()); } inline T value() const exprtk_override { - assert(condition_ .first); - assert(consequent_ .first); - assert(alternative_.first); - if (is_true(condition_)) return consequent_.first->value(); else @@ -6560,6 +7220,14 @@ namespace exprtk return expression_node::e_conditional; } + inline bool valid() const exprtk_override + { + return + condition_ .first && condition_ .first->valid() && + consequent_ .first && consequent_ .first->valid() && + alternative_.first && alternative_.first->valid() ; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(condition_ , node_delete_list); @@ -6594,13 +7262,11 @@ namespace exprtk { construct_branch_pair(condition_ , condition ); construct_branch_pair(consequent_, consequent); + assert(valid()); } inline T value() const exprtk_override { - assert(condition_ .first); - assert(consequent_.first); - if (is_true(condition_)) return consequent_.first->value(); else @@ -6612,6 +7278,13 @@ namespace exprtk return expression_node::e_conditional; } + inline bool valid() const exprtk_override + { + return + condition_ .first && condition_ .first->valid() && + consequent_.first && consequent_.first->valid() ; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(condition_ , node_delete_list); @@ -6653,7 +7326,7 @@ namespace exprtk typedef expression_node* expression_ptr; typedef std::pair branch_t; - break_node(expression_ptr ret = expression_ptr(0)) + explicit break_node(expression_ptr ret = expression_ptr(0)) { construct_branch_pair(return_, ret); } @@ -6666,7 +7339,7 @@ namespace exprtk throw break_exception(result); - #ifndef _MSC_VER + #if !defined(_MSC_VER) && !defined(__NVCOMPILER) return std::numeric_limits::quiet_NaN(); #endif } @@ -6699,7 +7372,7 @@ namespace exprtk inline T value() const exprtk_override { throw continue_exception(); - #ifndef _MSC_VER + #if !defined(_MSC_VER) && !defined(__NVCOMPILER) return std::numeric_limits::quiet_NaN(); #endif } @@ -6730,9 +7403,11 @@ namespace exprtk inline bool check() const { + assert(loop_runtime_check_); + if ( - (0 == loop_runtime_check_) || - ((++iteration_count_ <= max_loop_iterations_) && loop_runtime_check_->check()) + (++iteration_count_ <= max_loop_iterations_) && + loop_runtime_check_->check() ) { return true; @@ -6747,6 +7422,11 @@ namespace exprtk return false; } + bool valid() const + { + return 0 != loop_runtime_check_; + } + mutable _uint64_t iteration_count_; mutable loop_runtime_check_ptr loop_runtime_check_; const details::_uint64_t& max_loop_iterations_; @@ -6766,13 +7446,11 @@ namespace exprtk { construct_branch_pair(condition_, condition); construct_branch_pair(loop_body_, loop_body); + assert(valid()); } inline T value() const exprtk_override { - assert(condition_.first); - assert(loop_body_.first); - T result = T(0); while (is_true(condition_)) @@ -6788,6 +7466,13 @@ namespace exprtk return expression_node::e_while; } + inline bool valid() const exprtk_override + { + return + condition_.first && condition_.first->valid() && + loop_body_.first && loop_body_.first->valid() ; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(condition_ , node_delete_list); @@ -6820,12 +7505,12 @@ namespace exprtk loop_runtime_check_ptr loop_rt_chk) : parent_t(condition, loop_body) , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop) - {} + { + assert(valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); T result = T(0); @@ -6838,6 +7523,14 @@ namespace exprtk return result; } + + using parent_t::valid; + + bool valid() const exprtk_override exprtk_final + { + return parent_t::valid() && + loop_runtime_checker::valid(); + } }; template @@ -6853,13 +7546,11 @@ namespace exprtk { construct_branch_pair(condition_, condition); construct_branch_pair(loop_body_, loop_body); + assert(valid()); } inline T value() const exprtk_override { - assert(condition_.first); - assert(loop_body_.first); - T result = T(0); do @@ -6876,6 +7567,13 @@ namespace exprtk return expression_node::e_repeat; } + inline bool valid() const exprtk_override + { + return + condition_.first && condition_.first->valid() && + loop_body_.first && loop_body_.first->valid() ; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(condition_ , node_delete_list); @@ -6908,13 +7606,12 @@ namespace exprtk loop_runtime_check_ptr loop_rt_chk) : parent_t(condition, loop_body) , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop) - {} + { + assert(valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); loop_runtime_checker::reset(1); @@ -6927,6 +7624,14 @@ namespace exprtk return result; } + + using parent_t::valid; + + inline bool valid() const exprtk_override exprtk_final + { + return parent_t::valid() && + loop_runtime_checker::valid(); + } }; template @@ -6946,13 +7651,11 @@ namespace exprtk construct_branch_pair(condition_ , condition ); construct_branch_pair(incrementor_, incrementor); construct_branch_pair(loop_body_ , loop_body ); + assert(valid()); } inline T value() const exprtk_override { - assert(condition_.first); - assert(loop_body_.first); - T result = T(0); if (initialiser_.first) @@ -6982,6 +7685,11 @@ namespace exprtk return expression_node::e_for; } + inline bool valid() const exprtk_override + { + return condition_.first && loop_body_.first; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(initialiser_ , node_delete_list); @@ -7021,13 +7729,12 @@ namespace exprtk loop_runtime_check_ptr loop_rt_chk) : parent_t(initialiser, condition, incrementor, loop_body) , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop) - {} + { + assert(valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); loop_runtime_checker::reset(); @@ -7053,6 +7760,14 @@ namespace exprtk return result; } + + using parent_t::valid; + + inline bool valid() const exprtk_override exprtk_final + { + return parent_t::valid() && + loop_runtime_checker::valid(); + } }; #ifndef exprtk_disable_break_continue @@ -7067,13 +7782,12 @@ namespace exprtk while_loop_bc_node(expression_ptr condition, expression_ptr loop_body) : parent_t(condition, loop_body) - {} + { + assert(parent_t::valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); while (is_true(parent_t::condition_)) @@ -7109,13 +7823,12 @@ namespace exprtk loop_runtime_check_ptr loop_rt_chk) : parent_t(condition, loop_body) , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_while_loop) - {} + { + assert(valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); loop_runtime_checker::reset(); @@ -7136,6 +7849,14 @@ namespace exprtk return result; } + + using parent_t::valid; + + inline bool valid() const exprtk_override exprtk_final + { + return parent_t::valid() && + loop_runtime_checker::valid(); + } }; template @@ -7149,13 +7870,12 @@ namespace exprtk repeat_until_loop_bc_node(expression_ptr condition, expression_ptr loop_body) : parent_t(condition, loop_body) - {} + { + assert(parent_t::valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); do @@ -7179,8 +7899,8 @@ namespace exprtk template class repeat_until_loop_bc_rtc_node exprtk_final - : public repeat_until_loop_bc_node, - public loop_runtime_checker + : public repeat_until_loop_bc_node + , public loop_runtime_checker { public: @@ -7192,13 +7912,12 @@ namespace exprtk loop_runtime_check_ptr loop_rt_chk) : parent_t(condition, loop_body) , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_repeat_until_loop) - {} + { + assert(valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); loop_runtime_checker::reset(); @@ -7220,6 +7939,14 @@ namespace exprtk return result; } + + using parent_t::valid; + + inline bool valid() const exprtk_override exprtk_final + { + return parent_t::valid() && + loop_runtime_checker::valid(); + } }; template @@ -7235,13 +7962,12 @@ namespace exprtk expression_ptr incrementor, expression_ptr loop_body) : parent_t(initialiser, condition, incrementor, loop_body) - {} + { + assert(parent_t::valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); if (parent_t::initialiser_.first) @@ -7303,13 +8029,12 @@ namespace exprtk loop_runtime_check_ptr loop_rt_chk) : parent_t(initialiser, condition, incrementor, loop_body) , loop_runtime_checker(loop_rt_chk, loop_runtime_check::e_for_loop) - {} + { + assert(valid()); + } inline T value() const exprtk_override { - assert(parent_t::condition_.first); - assert(parent_t::loop_body_.first); - T result = T(0); loop_runtime_checker::reset(); @@ -7354,6 +8079,14 @@ namespace exprtk return result; } + + using parent_t::valid; + + inline bool valid() const exprtk_override exprtk_final + { + return parent_t::valid() && + loop_runtime_checker::valid(); + } }; #endif @@ -7376,7 +8109,7 @@ namespace exprtk for (std::size_t i = 0; i < arg_list.size(); ++i) { - if (arg_list[i]) + if (arg_list[i] && arg_list[i]->valid()) { construct_branch_pair(arg_list_[i], arg_list[i]); } @@ -7386,29 +8119,26 @@ namespace exprtk return; } } + + assert(valid()); } inline T value() const exprtk_override { - if (!arg_list_.empty()) + const std::size_t upper_bound = (arg_list_.size() - 1); + + for (std::size_t i = 0; i < upper_bound; i += 2) { - const std::size_t upper_bound = (arg_list_.size() - 1); + expression_ptr condition = arg_list_[i ].first; + expression_ptr consequent = arg_list_[i + 1].first; - for (std::size_t i = 0; i < upper_bound; i += 2) + if (is_true(condition)) { - expression_ptr condition = arg_list_[i ].first; - expression_ptr consequent = arg_list_[i + 1].first; - - if (is_true(condition)) - { - return consequent->value(); - } + return consequent->value(); } - - return arg_list_[upper_bound].first->value(); } - else - return std::numeric_limits::quiet_NaN(); + + return arg_list_[upper_bound].first->value(); } inline typename expression_node::node_type type() const exprtk_override exprtk_final @@ -7416,6 +8146,11 @@ namespace exprtk return expression_node::e_switch; } + inline bool valid() const exprtk_override + { + return !arg_list_.empty(); + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(arg_list_, node_delete_list); @@ -7469,7 +8204,7 @@ namespace exprtk for (std::size_t i = 0; i < arg_list.size(); ++i) { - if (arg_list[i]) + if (arg_list[i] && arg_list[i]->valid()) { construct_branch_pair(arg_list_[i], arg_list[i]); } @@ -7479,19 +8214,16 @@ namespace exprtk return; } } + + assert(valid()); } inline T value() const exprtk_override { - T result = T(0); - - if (arg_list_.empty()) - { - return std::numeric_limits::quiet_NaN(); - } - const std::size_t upper_bound = (arg_list_.size() - 1); + T result = T(0); + for (std::size_t i = 0; i < upper_bound; i += 2) { expression_ptr condition = arg_list_[i ].first; @@ -7511,6 +8243,11 @@ namespace exprtk return expression_node::e_mswitch; } + inline bool valid() const exprtk_override + { + return !arg_list_.empty() && (0 == (arg_list_.size() % 2)); + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(arg_list_, node_delete_list); @@ -7531,7 +8268,8 @@ namespace exprtk { public: - virtual ~ivariable() {} + virtual ~ivariable() + {} virtual T& ref() = 0; virtual const T& ref() const = 0; @@ -7539,8 +8277,8 @@ namespace exprtk template class variable_node exprtk_final - : public expression_node, - public ivariable + : public expression_node + , public ivariable { public: @@ -7677,7 +8415,7 @@ namespace exprtk (std::numeric_limits::max() == r1 ) ) { - r1 = size - 1; + r1 = size; } cache.first = r0; @@ -7692,12 +8430,12 @@ namespace exprtk inline std::size_t const_size() const { - return (n1_c.second - n0_c.second + 1); + return (n1_c.second - n0_c.second); } inline std::size_t cache_size() const { - return (cache.second - cache.first + 1); + return (cache.second - cache.first); } std::pair n0_e; @@ -7711,16 +8449,20 @@ namespace exprtk const std::size_t r1, const std::size_t size) const { - if (r0 >= size) + if (r0 > size) { - throw std::runtime_error("range error: (r0 < 0) || (r0 >= size)"); + throw std::runtime_error("range error: (r0 < 0) || (r0 > size)"); + #if !defined(_MSC_VER) && !defined(__NVCOMPILER) return false; + #endif } - if (r1 >= size) + if (r1 > size) { - throw std::runtime_error("range error: (r1 < 0) || (r1 >= size)"); + throw std::runtime_error("range error: (r1 < 0) || (r1 > size)"); + #if !defined(_MSC_VER) && !defined(__NVCOMPILER) return false; + #endif } return (r0 <= r1); @@ -7762,19 +8504,22 @@ namespace exprtk typedef vector_node* vector_node_ptr; typedef vec_data_store vds_t; - virtual ~vector_interface() {} + virtual ~vector_interface() + {} + + virtual std::size_t size () const = 0; - virtual std::size_t size () const = 0; + virtual std::size_t base_size() const = 0; - virtual vector_node_ptr vec() const = 0; + virtual vector_node_ptr vec () const = 0; - virtual vector_node_ptr vec() = 0; + virtual vector_node_ptr vec () = 0; - virtual vds_t& vds () = 0; + virtual vds_t& vds () = 0; - virtual const vds_t& vds () const = 0; + virtual const vds_t& vds () const = 0; - virtual bool side_effect () const { return false; } + virtual bool side_effect () const { return false; } }; template @@ -7801,6 +8546,12 @@ namespace exprtk , vds_(vds) {} + ~vector_node() + { + assert(valid()); + vector_holder_->remove_ref(&vds_.ref()); + } + inline T value() const exprtk_override { return vds().data()[0]; @@ -7821,9 +8572,19 @@ namespace exprtk return expression_node::e_vector; } + inline bool valid() const exprtk_override + { + return vector_holder_; + } + std::size_t size() const exprtk_override { - return vds().size(); + return vec_holder().size(); + } + + std::size_t base_size() const exprtk_override + { + return vec_holder().base_size(); } vds_t& vds() exprtk_override @@ -7841,16 +8602,65 @@ namespace exprtk return (*vector_holder_); } + inline vector_holder_t& vec_holder() const + { + return (*vector_holder_); + } + private: vector_holder_t* vector_holder_; vds_t vds_; }; + template + class vector_size_node exprtk_final + : public expression_node + { + public: + + typedef expression_node* expression_ptr; + typedef vector_holder vector_holder_t; + + explicit vector_size_node(vector_holder_t* vh) + : vector_holder_(vh) + {} + + ~vector_size_node() + { + assert(valid()); + } + + inline T value() const exprtk_override + { + assert(vector_holder_); + return static_cast(vector_holder_->size()); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecsize; + } + + inline bool valid() const exprtk_override + { + return vector_holder_ && vector_holder_->size(); + } + + inline vector_holder_t* vec_holder() + { + return vector_holder_; + } + + private: + + vector_holder_t* vector_holder_; + }; + template class vector_elem_node exprtk_final - : public expression_node, - public ivariable + : public expression_node + , public ivariable { public: @@ -7859,26 +8669,30 @@ namespace exprtk typedef vector_holder_t* vector_holder_ptr; typedef std::pair branch_t; - vector_elem_node(expression_ptr index, vector_holder_ptr vec_holder) - : vec_holder_(vec_holder) + vector_elem_node(expression_ptr vec_node, + expression_ptr index, + vector_holder_ptr vec_holder) + : vector_holder_(vec_holder) , vector_base_((*vec_holder)[0]) { - construct_branch_pair(index_, index); + construct_branch_pair(vector_node_, vec_node); + construct_branch_pair(index_ , index ); + assert(valid()); } inline T value() const exprtk_override { - return *(vector_base_ + static_cast(details::numeric::to_int64(index_.first->value()))); + return *access_vector(); } inline T& ref() exprtk_override { - return *(vector_base_ + static_cast(details::numeric::to_int64(index_.first->value()))); + return *access_vector(); } inline const T& ref() const exprtk_override { - return *(vector_base_ + static_cast(details::numeric::to_int64(index_.first->value()))); + return *access_vector(); } inline typename expression_node::node_type type() const exprtk_override @@ -7886,67 +8700,96 @@ namespace exprtk return expression_node::e_vecelem; } + inline bool valid() const exprtk_override + { + return + vector_holder_ && + index_.first && + vector_node_.first && + index_.first->valid() && + vector_node_.first->valid(); + } + inline vector_holder_t& vec_holder() { - return (*vec_holder_); + return (*vector_holder_); } void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::collect(index_, node_delete_list); + expression_node::ndb_t::collect(vector_node_, node_delete_list); + expression_node::ndb_t::collect(index_ , node_delete_list); } std::size_t node_depth() const exprtk_override { - return expression_node::ndb_t::compute_node_depth(index_); + return expression_node::ndb_t::compute_node_depth + (vector_node_, index_); } private: - vector_holder_ptr vec_holder_; + inline T* access_vector() const + { + vector_node_.first->value(); + return (vector_base_ + details::numeric::to_uint64(index_.first->value())); + } + + vector_holder_ptr vector_holder_; T* vector_base_; + branch_t vector_node_; branch_t index_; }; template - class rebasevector_elem_node exprtk_final - : public expression_node, - public ivariable + class vector_celem_node exprtk_final + : public expression_node + , public ivariable { public: typedef expression_node* expression_ptr; typedef vector_holder vector_holder_t; typedef vector_holder_t* vector_holder_ptr; - typedef vec_data_store vds_t; typedef std::pair branch_t; - rebasevector_elem_node(expression_ptr index, vector_holder_ptr vec_holder) - : vector_holder_(vec_holder) - , vds_((*vector_holder_).size(),(*vector_holder_)[0]) + vector_celem_node(expression_ptr vec_node, + const std::size_t index, + vector_holder_ptr vec_holder) + : index_(index) + , vector_holder_(vec_holder) + , vector_base_((*vec_holder)[0]) { - vector_holder_->set_ref(&vds_.ref()); - construct_branch_pair(index_, index); + construct_branch_pair(vector_node_, vec_node); + assert(valid()); } inline T value() const exprtk_override { - return *(vds_.data() + static_cast(details::numeric::to_int64(index_.first->value()))); + return *access_vector(); } inline T& ref() exprtk_override { - return *(vds_.data() + static_cast(details::numeric::to_int64(index_.first->value()))); + return *access_vector(); } inline const T& ref() const exprtk_override { - return *(vds_.data() + static_cast(details::numeric::to_int64(index_.first->value()))); + return *access_vector(); } inline typename expression_node::node_type type() const exprtk_override { - return expression_node::e_rbvecelem; + return expression_node::e_veccelem; + } + + inline bool valid() const exprtk_override + { + return + vector_holder_ && + vector_node_.first && + vector_node_.first->valid(); } inline vector_holder_t& vec_holder() @@ -7956,59 +8799,82 @@ namespace exprtk void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(index_, node_delete_list); + expression_node::ndb_t::collect(vector_node_, node_delete_list); } std::size_t node_depth() const exprtk_override { - return expression_node::ndb_t::compute_node_depth(index_); + return expression_node::ndb_t::compute_node_depth(vector_node_); } private: + inline T* access_vector() const + { + vector_node_.first->value(); + return (vector_base_ + index_); + } + + const std::size_t index_; vector_holder_ptr vector_holder_; - vds_t vds_; - branch_t index_; + T* vector_base_; + branch_t vector_node_; }; template - class rebasevector_celem_node exprtk_final - : public expression_node, - public ivariable + class vector_elem_rtc_node exprtk_final + : public expression_node + , public ivariable { public: - typedef expression_node* expression_ptr; - typedef vector_holder vector_holder_t; - typedef vector_holder_t* vector_holder_ptr; - typedef vec_data_store vds_t; + typedef expression_node* expression_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; + typedef std::pair branch_t; - rebasevector_celem_node(const std::size_t index, vector_holder_ptr vec_holder) - : index_(index) - , vector_holder_(vec_holder) - , vds_((*vector_holder_).size(),(*vector_holder_)[0]) + vector_elem_rtc_node(expression_ptr vec_node, + expression_ptr index, + vector_holder_ptr vec_holder, + vector_access_runtime_check_ptr vec_rt_chk) + : vector_holder_(vec_holder) + , vector_base_((*vec_holder)[0]) + , vec_rt_chk_(vec_rt_chk) + , max_vector_index_(vector_holder_->size() - 1) { - vector_holder_->set_ref(&vds_.ref()); + construct_branch_pair(vector_node_, vec_node); + construct_branch_pair(index_ , index ); + assert(valid()); } inline T value() const exprtk_override { - return *(vds_.data() + index_); + return *access_vector(); } inline T& ref() exprtk_override { - return *(vds_.data() + index_); + return *access_vector(); } inline const T& ref() const exprtk_override { - return *(vds_.data() + index_); + return *access_vector(); } inline typename expression_node::node_type type() const exprtk_override { - return expression_node::e_rbveccelem; + return expression_node::e_vecelemrtc; + } + + inline bool valid() const exprtk_override + { + return + vector_holder_ && + index_.first && + vector_node_.first && + index_.first->valid() && + vector_node_.first->valid(); } inline vector_holder_t& vec_holder() @@ -8016,451 +8882,1432 @@ namespace exprtk return (*vector_holder_); } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(vector_node_, node_delete_list); + expression_node::ndb_t::collect(index_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth + (vector_node_, index_); + } + private: - const std::size_t index_; + inline T* access_vector() const + { + const _uint64_t index = details::numeric::to_uint64(index_.first->value()); + vector_node_.first->value(); + + if (index <= max_vector_index_) + { + return (vector_holder_->data() + index); + } + + assert(vec_rt_chk_); + + vector_access_runtime_check::violation_context context; + context.base_ptr = reinterpret_cast(vector_base_); + context.end_ptr = reinterpret_cast(vector_base_ + vector_holder_->size()); + context.access_ptr = reinterpret_cast(vector_base_ + index); + context.type_size = sizeof(T); + + return vec_rt_chk_->handle_runtime_violation(context) ? + reinterpret_cast(context.access_ptr) : + vector_base_ ; + } + vector_holder_ptr vector_holder_; - vds_t vds_; + T* vector_base_; + branch_t vector_node_; + branch_t index_; + vector_access_runtime_check_ptr vec_rt_chk_; + const std::size_t max_vector_index_; }; template - class vector_assignment_node exprtk_final : public expression_node + class vector_celem_rtc_node exprtk_final + : public expression_node + , public ivariable { public: - typedef expression_node* expression_ptr; + typedef expression_node* expression_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; + typedef std::pair branch_t; - vector_assignment_node(T* vector_base, - const std::size_t& size, - const std::vector& initialiser_list, - const bool single_value_initialse) - : vector_base_(vector_base) - , initialiser_list_(initialiser_list) - , size_(size) - , single_value_initialse_(single_value_initialse) - {} + vector_celem_rtc_node(expression_ptr vec_node, + const std::size_t index, + vector_holder_ptr vec_holder, + vector_access_runtime_check_ptr vec_rt_chk) + : index_(index) + , max_vector_index_(vec_holder->size() - 1) + , vector_holder_(vec_holder) + , vector_base_((*vec_holder)[0]) + , vec_rt_chk_(vec_rt_chk) + { + construct_branch_pair(vector_node_, vec_node); + assert(valid()); + } inline T value() const exprtk_override { - if (single_value_initialse_) - { - for (std::size_t i = 0; i < size_; ++i) - { - *(vector_base_ + i) = initialiser_list_[0]->value(); - } - } - else - { - const std::size_t initialiser_list_size = initialiser_list_.size(); - - for (std::size_t i = 0; i < initialiser_list_size; ++i) - { - *(vector_base_ + i) = initialiser_list_[i]->value(); - } + return *access_vector(); + } - if (initialiser_list_size < size_) - { - for (std::size_t i = initialiser_list_size; i < size_; ++i) - { - *(vector_base_ + i) = T(0); - } - } - } + inline T& ref() exprtk_override + { + return *access_vector(); + } - return *(vector_base_); + inline const T& ref() const exprtk_override + { + return *access_vector(); } inline typename expression_node::node_type type() const exprtk_override { - return expression_node::e_vecdefass; + return expression_node::e_veccelemrtc; + } + + inline bool valid() const exprtk_override + { + return + vector_holder_ && + vector_node_.first && + vector_node_.first->valid(); + } + + inline vector_holder_t& vec_holder() + { + return (*vector_holder_); } void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + expression_node::ndb_t::collect(vector_node_, node_delete_list); } std::size_t node_depth() const exprtk_override { - return expression_node::ndb_t::compute_node_depth(initialiser_list_); + return expression_node::ndb_t::compute_node_depth(vector_node_); } private: - vector_assignment_node(const vector_assignment_node&) exprtk_delete; - vector_assignment_node& operator=(const vector_assignment_node&) exprtk_delete; + inline T* access_vector() const + { + vector_node_.first->value(); - mutable T* vector_base_; - std::vector initialiser_list_; - const std::size_t size_; - const bool single_value_initialse_; + if (index_ <= max_vector_index_) + { + return (vector_holder_->data() + index_); + } + + assert(vec_rt_chk_); + + vector_access_runtime_check::violation_context context; + context.base_ptr = reinterpret_cast(vector_base_); + context.end_ptr = reinterpret_cast(vector_base_ + vector_holder_->size()); + context.access_ptr = reinterpret_cast(vector_base_ + index_); + context.type_size = sizeof(T); + + return vec_rt_chk_->handle_runtime_violation(context) ? + reinterpret_cast(context.access_ptr) : + vector_base_ ; + } + + const std::size_t index_; + const std::size_t max_vector_index_; + vector_holder_ptr vector_holder_; + T* vector_base_; + branch_t vector_node_; + vector_access_runtime_check_ptr vec_rt_chk_; }; template - class swap_node exprtk_final : public expression_node + class rebasevector_elem_node exprtk_final + : public expression_node + , public ivariable { public: - typedef expression_node* expression_ptr; - typedef variable_node* variable_node_ptr; + typedef expression_node* expression_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; + typedef vec_data_store vds_t; + typedef std::pair branch_t; - swap_node(variable_node_ptr var0, variable_node_ptr var1) - : var0_(var0) - , var1_(var1) - {} + rebasevector_elem_node(expression_ptr vec_node, + expression_ptr index, + vector_holder_ptr vec_holder) + : vector_holder_(vec_holder) + { + construct_branch_pair(vector_node_, vec_node); + construct_branch_pair(index_ , index ); + assert(valid()); + } inline T value() const exprtk_override { - std::swap(var0_->ref(),var1_->ref()); - return var1_->ref(); + return *access_vector(); } - inline typename expression_node::node_type type() const exprtk_override + inline T& ref() exprtk_override { - return expression_node::e_swap; + return *access_vector(); } - private: - - variable_node_ptr var0_; - variable_node_ptr var1_; - }; + inline const T& ref() const exprtk_override + { + return *access_vector(); + } - template - class swap_generic_node exprtk_final : public binary_node - { - public: + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_rbvecelem; + } - typedef expression_node* expression_ptr; - typedef ivariable* ivariable_ptr; + inline bool valid() const exprtk_override + { + return + vector_holder_ && + index_.first && + vector_node_.first && + index_.first->valid() && + vector_node_.first->valid(); + } - swap_generic_node(expression_ptr var0, expression_ptr var1) - : binary_node(details::e_swap, var0, var1) - , var0_(dynamic_cast(var0)) - , var1_(dynamic_cast(var1)) - {} + inline vector_holder_t& vec_holder() + { + return (*vector_holder_); + } - inline T value() const exprtk_override + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - std::swap(var0_->ref(),var1_->ref()); - return var1_->ref(); + expression_node::ndb_t::collect(vector_node_, node_delete_list); + expression_node::ndb_t::collect(index_, node_delete_list); } - inline typename expression_node::node_type type() const exprtk_override + std::size_t node_depth() const exprtk_override { - return expression_node::e_swap; + return expression_node::ndb_t::compute_node_depth + (vector_node_, index_); } private: - ivariable_ptr var0_; - ivariable_ptr var1_; + inline T* access_vector() const + { + vector_node_.first->value(); + return (vector_holder_->data() + details::numeric::to_uint64(index_.first->value())); + } + + vector_holder_ptr vector_holder_; + branch_t vector_node_; + branch_t index_; }; template - class swap_vecvec_node exprtk_final - : public binary_node - , public vector_interface + class rebasevector_celem_node exprtk_final + : public expression_node + , public ivariable { public: typedef expression_node* expression_ptr; - typedef vector_node * vector_node_ptr; - typedef vec_data_store vds_t; - - using binary_node::branch; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; + typedef std::pair branch_t; - swap_vecvec_node(expression_ptr branch0, - expression_ptr branch1) - : binary_node(details::e_swap, branch0, branch1) - , vec0_node_ptr_(0) - , vec1_node_ptr_(0) - , vec_size_ (0) - , initialised_ (false) + rebasevector_celem_node(expression_ptr vec_node, + const std::size_t index, + vector_holder_ptr vec_holder) + : index_(index) + , vector_holder_(vec_holder) { - if (is_ivector_node(branch(0))) - { - vector_interface* vi = reinterpret_cast*>(0); - - if (0 != (vi = dynamic_cast*>(branch(0)))) - { - vec0_node_ptr_ = vi->vec(); - vds() = vi->vds(); - } - } - - if (is_ivector_node(branch(1))) - { - vector_interface* vi = reinterpret_cast*>(0); - - if (0 != (vi = dynamic_cast*>(branch(1)))) - { - vec1_node_ptr_ = vi->vec(); - } - } - - if (vec0_node_ptr_ && vec1_node_ptr_) - { - vec_size_ = std::min(vec0_node_ptr_->vds().size(), - vec1_node_ptr_->vds().size()); - - initialised_ = true; - } - - assert(initialised_); + construct_branch_pair(vector_node_, vec_node); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); - - binary_node::branch(0)->value(); - binary_node::branch(1)->value(); - - T* vec0 = vec0_node_ptr_->vds().data(); - T* vec1 = vec1_node_ptr_->vds().data(); - - for (std::size_t i = 0; i < vec_size_; ++i) - { - std::swap(vec0[i],vec1[i]); - } - - return vec1_node_ptr_->value(); - } - else - return std::numeric_limits::quiet_NaN(); + vector_node_.first->value(); + return ref();; } - vector_node_ptr vec() const exprtk_override + inline T& ref() exprtk_override { - return vec0_node_ptr_; + return *(vector_holder_->data() + index_); } - vector_node_ptr vec() exprtk_override + inline const T& ref() const exprtk_override { - return vec0_node_ptr_; + return *(vector_holder_->data() + index_); } inline typename expression_node::node_type type() const exprtk_override { - return expression_node::e_vecvecswap; + return expression_node::e_rbveccelem; } - std::size_t size() const exprtk_override + inline bool valid() const exprtk_override { - return vec_size_; + return + vector_holder_ && + vector_node_.first && + vector_node_.first->valid(); } - vds_t& vds() exprtk_override + inline vector_holder_t& vec_holder() { - return vds_; + return (*vector_holder_); } - const vds_t& vds() const exprtk_override + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - return vds_; + expression_node::ndb_t::collect(vector_node_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(vector_node_); } private: - vector_node* vec0_node_ptr_; - vector_node* vec1_node_ptr_; - std::size_t vec_size_; - bool initialised_; - vds_t vds_; + const std::size_t index_; + vector_holder_ptr vector_holder_; + branch_t vector_node_; }; - #ifndef exprtk_disable_string_capabilities template - class stringvar_node exprtk_final - : public expression_node , - public string_base_node, - public range_interface + class rebasevector_elem_rtc_node exprtk_final + : public expression_node + , public ivariable { public: - typedef typename range_interface::range_t range_t; - - static std::string null_value; - - explicit stringvar_node() - : value_(&null_value) - {} - - explicit stringvar_node(std::string& v) - : value_(&v) - { - rp_.n0_c = std::make_pair(true,0); - rp_.n1_c = std::make_pair(true,v.size() - 1); - rp_.cache.first = rp_.n0_c.second; - rp_.cache.second = rp_.n1_c.second; - } + typedef expression_node* expression_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; + typedef std::pair branch_t; - inline bool operator <(const stringvar_node& v) const + rebasevector_elem_rtc_node(expression_ptr vec_node, + expression_ptr index, + vector_holder_ptr vec_holder, + vector_access_runtime_check_ptr vec_rt_chk) + : vector_holder_(vec_holder) + , vec_rt_chk_(vec_rt_chk) { - return this < (&v); + construct_branch_pair(vector_node_, vec_node); + construct_branch_pair(index_ , index ); + assert(valid()); } inline T value() const exprtk_override { - rp_.n1_c.second = (*value_).size() - 1; - rp_.cache.second = rp_.n1_c.second; - - return std::numeric_limits::quiet_NaN(); + return *access_vector(); } - std::string str() const exprtk_override + inline T& ref() exprtk_override { - return ref(); + return *access_vector(); } - char_cptr base() const exprtk_override + inline const T& ref() const exprtk_override { - return &(*value_)[0]; + return *access_vector(); } - std::size_t size() const exprtk_override + inline typename expression_node::node_type type() const exprtk_override { - return ref().size(); + return expression_node::e_rbvecelemrtc; } - std::string& ref() + inline bool valid() const exprtk_override { - return (*value_); + return + vector_holder_ && + index_.first && + vector_node_.first && + index_.first->valid() && + vector_node_.first->valid(); } - const std::string& ref() const + inline vector_holder_t& vec_holder() { - return (*value_); + return (*vector_holder_); } - range_t& range_ref() exprtk_override + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - return rp_; + expression_node::ndb_t::collect(vector_node_, node_delete_list); + expression_node::ndb_t::collect(index_ , node_delete_list); } - const range_t& range_ref() const exprtk_override + std::size_t node_depth() const exprtk_override { - return rp_; + return expression_node::ndb_t::compute_node_depth + (vector_node_, index_); } - inline typename expression_node::node_type type() const exprtk_override - { - return expression_node::e_stringvar; - } + private: - void rebase(std::string& s) + inline T* access_vector() const { - value_ = &s; - rp_.n0_c = std::make_pair(true,0); - rp_.n1_c = std::make_pair(true,value_->size() - 1); - rp_.cache.first = rp_.n0_c.second; - rp_.cache.second = rp_.n1_c.second; - } + vector_node_.first->value(); + const _uint64_t index = details::numeric::to_uint64(index_.first->value()); - private: + if (index <= (vector_holder_->size() - 1)) + { + return (vector_holder_->data() + index); + } - std::string* value_; - mutable range_t rp_; - }; + assert(vec_rt_chk_); - template - std::string stringvar_node::null_value = std::string(""); + vector_access_runtime_check::violation_context context; + context.base_ptr = reinterpret_cast(vector_holder_->data()); + context.end_ptr = reinterpret_cast(vector_holder_->data() + vector_holder_->size()); + context.access_ptr = reinterpret_cast(vector_holder_->data() + index); + context.type_size = sizeof(T); + + return vec_rt_chk_->handle_runtime_violation(context) ? + reinterpret_cast(context.access_ptr) : + vector_holder_->data() ; + } + + vector_holder_ptr vector_holder_; + branch_t vector_node_; + branch_t index_; + vector_access_runtime_check_ptr vec_rt_chk_; + }; template - class string_range_node exprtk_final - : public expression_node , - public string_base_node, - public range_interface + class rebasevector_celem_rtc_node exprtk_final + : public expression_node + , public ivariable { public: - typedef typename range_interface::range_t range_t; - - static std::string null_value; - - explicit string_range_node(std::string& v, const range_t& rp) - : value_(&v) - , rp_(rp) - {} - - virtual ~string_range_node() - { - rp_.free(); - } + typedef expression_node* expression_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; + typedef std::pair branch_t; - inline bool operator <(const string_range_node& v) const + rebasevector_celem_rtc_node(expression_ptr vec_node, + const std::size_t index, + vector_holder_ptr vec_holder, + vector_access_runtime_check_ptr vec_rt_chk) + : index_(index) + , vector_holder_(vec_holder) + , vector_base_((*vec_holder)[0]) + , vec_rt_chk_(vec_rt_chk) { - return this < (&v); + construct_branch_pair(vector_node_, vec_node); + assert(valid()); } inline T value() const exprtk_override { - return std::numeric_limits::quiet_NaN(); + return *access_vector(); } - inline std::string str() const exprtk_override + inline T& ref() exprtk_override { - return (*value_); + return *access_vector(); } - char_cptr base() const exprtk_override + inline const T& ref() const exprtk_override { - return &(*value_)[0]; + return *access_vector(); } - std::size_t size() const exprtk_override + inline typename expression_node::node_type type() const exprtk_override { - return ref().size(); + return expression_node::e_rbveccelemrtc; } - inline range_t range() const + inline bool valid() const exprtk_override { - return rp_; + return + vector_holder_ && + vector_node_.first && + vector_node_.first->valid(); } - inline virtual std::string& ref() + inline vector_holder_t& vec_holder() { - return (*value_); + return (*vector_holder_); } - inline virtual const std::string& ref() const + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - return (*value_); + expression_node::ndb_t::collect(vector_node_, node_delete_list); } - inline range_t& range_ref() exprtk_override + std::size_t node_depth() const exprtk_override { - return rp_; + return expression_node::ndb_t::compute_node_depth(vector_node_); } - inline const range_t& range_ref() const exprtk_override - { - return rp_; - } + private: - inline typename expression_node::node_type type() const exprtk_override + inline T* access_vector() const { - return expression_node::e_stringvarrng; - } + vector_node_.first->value(); - private: + if (index_ <= vector_holder_->size() - 1) + { + return (vector_holder_->data() + index_); + } - std::string* value_; - range_t rp_; + assert(vec_rt_chk_); + + vector_access_runtime_check::violation_context context; + context.base_ptr = reinterpret_cast(vector_base_); + context.end_ptr = reinterpret_cast(vector_base_ + vector_holder_->size()); + context.access_ptr = reinterpret_cast(vector_base_ + index_); + context.type_size = sizeof(T); + + return vec_rt_chk_->handle_runtime_violation(context) ? + reinterpret_cast(context.access_ptr) : + vector_base_ ; + } + + const std::size_t index_; + vector_holder_ptr vector_holder_; + T* vector_base_; + branch_t vector_node_; + vector_access_runtime_check_ptr vec_rt_chk_; }; template - std::string string_range_node::null_value = std::string(""); + class vector_initialisation_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_initialisation_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list, + const bool single_value_initialse) + : vector_base_(vector_base) + , initialiser_list_(initialiser_list) + , size_(size) + , single_value_initialse_(single_value_initialse) + , zero_value_initialse_(false) + , const_nonzero_literal_value_initialse_(false) + , single_initialiser_value_(T(0)) + { + if (single_value_initialse_) + { + if (initialiser_list_.empty()) + zero_value_initialse_ = true; + else if ( + (initialiser_list_.size() == 1) && + details::is_constant_node(initialiser_list_[0]) && + (T(0) == initialiser_list_[0]->value()) + ) + { + zero_value_initialse_ = true; + } + else + { + assert(initialiser_list_.size() == 1); + + if (details::is_constant_node(initialiser_list_[0])) + { + const_nonzero_literal_value_initialse_ = true; + single_initialiser_value_ = initialiser_list_[0]->value(); + assert(T(0) != single_initialiser_value_); + } + } + } + } + + inline T value() const exprtk_override + { + if (single_value_initialse_) + { + if (zero_value_initialse_) + { + details::set_zero_value(vector_base_, size_); + } + else if (const_nonzero_literal_value_initialse_) + { + for (std::size_t i = 0; i < size_; ++i) + { + *(vector_base_ + i) = single_initialiser_value_; + } + } + else + { + for (std::size_t i = 0; i < size_; ++i) + { + *(vector_base_ + i) = initialiser_list_[0]->value(); + } + } + } + else + { + const std::size_t initialiser_list_size = initialiser_list_.size(); + + for (std::size_t i = 0; i < initialiser_list_size; ++i) + { + *(vector_base_ + i) = initialiser_list_[i]->value(); + } + + if (initialiser_list_size < size_) + { + details::set_zero_value( + vector_base_ + initialiser_list_size, + (size_ - initialiser_list_size)); + } + } + + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_; + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_initialisation_node(const vector_initialisation_node&) exprtk_delete; + vector_initialisation_node& operator=(const vector_initialisation_node&) exprtk_delete; + + mutable T* vector_base_; + std::vector initialiser_list_; + const std::size_t size_; + const bool single_value_initialse_; + bool zero_value_initialse_; + bool const_nonzero_literal_value_initialse_; + T single_initialiser_value_; + }; + + template + class vector_init_zero_value_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_init_zero_value_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list) + : vector_base_(vector_base) + , size_(size) + , initialiser_list_(initialiser_list) + {} + + inline T value() const exprtk_override + { + details::set_zero_value(vector_base_, size_); + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_; + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_init_zero_value_node(const vector_init_zero_value_node&) exprtk_delete; + vector_init_zero_value_node& operator=(const vector_init_zero_value_node&) exprtk_delete; + + mutable T* vector_base_; + const std::size_t size_; + std::vector initialiser_list_; + }; + + template + class vector_init_single_constvalue_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_init_single_constvalue_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list) + : vector_base_(vector_base) + , size_(size) + , initialiser_list_(initialiser_list) + { + single_initialiser_value_ = initialiser_list_[0]->value(); + assert(valid()); + } + + inline T value() const exprtk_override + { + for (std::size_t i = 0; i < size_; ++i) + { + *(vector_base_ + i) = single_initialiser_value_; + } + + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_ && + (initialiser_list_.size() == 1) && + (details::is_constant_node(initialiser_list_[0])) && + (single_initialiser_value_ != T(0)); + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_init_single_constvalue_node(const vector_init_single_constvalue_node&) exprtk_delete; + vector_init_single_constvalue_node& operator=(const vector_init_single_constvalue_node&) exprtk_delete; + + mutable T* vector_base_; + const std::size_t size_; + std::vector initialiser_list_; + T single_initialiser_value_; + }; + + template + class vector_init_single_value_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_init_single_value_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list) + : vector_base_(vector_base) + , size_(size) + , initialiser_list_(initialiser_list) + { + assert(valid()); + } + + inline T value() const exprtk_override + { + expression_node& node = *initialiser_list_[0]; + + for (std::size_t i = 0; i < size_; ++i) + { + *(vector_base_ + i) = node.value(); + } + + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_ && + (initialiser_list_.size() == 1) && + !details::is_constant_node(initialiser_list_[0]); + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_init_single_value_node(const vector_init_single_value_node&) exprtk_delete; + vector_init_single_value_node& operator=(const vector_init_single_value_node&) exprtk_delete; + + mutable T* vector_base_; + const std::size_t size_; + std::vector initialiser_list_; + }; + + template + class vector_init_iota_constconst_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_init_iota_constconst_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list) + : vector_base_(vector_base) + , size_(size) + , initialiser_list_(initialiser_list) + { + base_value_ = initialiser_list_[0]->value(); + increment_value_ = initialiser_list_[1]->value(); + + assert(valid()); + } + + inline T value() const exprtk_override + { + T value = base_value_; + + for (std::size_t i = 0; i < size_; ++i, value += increment_value_) + { + *(vector_base_ + i) = value; + } + + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_ && + (initialiser_list_.size() == 2) && + (details::is_constant_node(initialiser_list_[0])) && + (details::is_constant_node(initialiser_list_[1])) ; + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_init_iota_constconst_node(const vector_init_iota_constconst_node&) exprtk_delete; + vector_init_iota_constconst_node& operator=(const vector_init_iota_constconst_node&) exprtk_delete; + + mutable T* vector_base_; + const std::size_t size_; + std::vector initialiser_list_; + T base_value_; + T increment_value_; + }; + + template + class vector_init_iota_constnconst_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_init_iota_constnconst_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list) + : vector_base_(vector_base) + , size_(size) + , initialiser_list_(initialiser_list) + { + assert(valid()); + base_value_ = initialiser_list_[0]->value(); + } + + inline T value() const exprtk_override + { + T value = base_value_; + expression_node& increment = *initialiser_list_[1]; + + for (std::size_t i = 0; i < size_; ++i, value += increment.value()) + { + *(vector_base_ + i) = value; + } + + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_ && + (initialiser_list_.size() == 2) && + ( details::is_constant_node(initialiser_list_[0])) && + (!details::is_constant_node(initialiser_list_[1])); + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_init_iota_constnconst_node(const vector_init_iota_constnconst_node&) exprtk_delete; + vector_init_iota_constnconst_node& operator=(const vector_init_iota_constnconst_node&) exprtk_delete; + + mutable T* vector_base_; + const std::size_t size_; + std::vector initialiser_list_; + T base_value_; + }; + + template + class vector_init_iota_nconstconst_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_init_iota_nconstconst_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list) + : vector_base_(vector_base) + , size_(size) + , initialiser_list_(initialiser_list) + { + assert(valid()); + } + + inline T value() const exprtk_override + { + T value = initialiser_list_[0]->value(); + const T increment = initialiser_list_[1]->value(); + + for (std::size_t i = 0; i < size_; ++i, value += increment) + { + *(vector_base_ + i) = value; + } + + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_ && + (initialiser_list_.size() == 2) && + (!details::is_constant_node(initialiser_list_[0])) && + (details::is_constant_node(initialiser_list_[1])); + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_init_iota_nconstconst_node(const vector_init_iota_nconstconst_node&) exprtk_delete; + vector_init_iota_nconstconst_node& operator=(const vector_init_iota_nconstconst_node&) exprtk_delete; + + mutable T* vector_base_; + const std::size_t size_; + std::vector initialiser_list_; + }; + + template + class vector_init_iota_nconstnconst_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + + vector_init_iota_nconstnconst_node(T* vector_base, + const std::size_t& size, + const std::vector& initialiser_list) + : vector_base_(vector_base) + , size_(size) + , initialiser_list_(initialiser_list) + { + assert(valid()); + } + + inline T value() const exprtk_override + { + T value = initialiser_list_[0]->value(); + expression_node& increment = *initialiser_list_[1]; + + for (std::size_t i = 0; i < size_; ++i, value += increment.value()) + { + *(vector_base_ + i) = value; + } + + return *(vector_base_); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecinit; + } + + inline bool valid() const exprtk_override + { + return vector_base_ && + (initialiser_list_.size() == 2) && + (!details::is_constant_node(initialiser_list_[0])) && + (!details::is_constant_node(initialiser_list_[1])); + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(initialiser_list_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(initialiser_list_); + } + + private: + + vector_init_iota_nconstnconst_node(const vector_init_iota_nconstnconst_node&) exprtk_delete; + vector_init_iota_nconstnconst_node& operator=(const vector_init_iota_nconstnconst_node&) exprtk_delete; + + mutable T* vector_base_; + const std::size_t size_; + std::vector initialiser_list_; + }; + + template + class swap_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + typedef variable_node* variable_node_ptr; + + swap_node(variable_node_ptr var0, variable_node_ptr var1) + : var0_(var0) + , var1_(var1) + {} + + inline T value() const exprtk_override + { + std::swap(var0_->ref(),var1_->ref()); + return var1_->ref(); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_swap; + } + + private: + + variable_node_ptr var0_; + variable_node_ptr var1_; + }; + + template + class swap_generic_node exprtk_final : public binary_node + { + public: + + typedef expression_node* expression_ptr; + typedef ivariable* ivariable_ptr; + + swap_generic_node(expression_ptr var0, expression_ptr var1) + : binary_node(details::e_swap, var0, var1) + , var0_(dynamic_cast(var0)) + , var1_(dynamic_cast(var1)) + {} + + inline T value() const exprtk_override + { + std::swap(var0_->ref(),var1_->ref()); + return var1_->ref(); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_swap; + } + + private: + + ivariable_ptr var0_; + ivariable_ptr var1_; + }; + + template + class swap_vecvec_node exprtk_final + : public binary_node + , public vector_interface + { + public: + + typedef expression_node* expression_ptr; + typedef vector_node * vector_node_ptr; + typedef vec_data_store vds_t; + + using binary_node::branch; + + swap_vecvec_node(expression_ptr branch0, + expression_ptr branch1) + : binary_node(details::e_swap, branch0, branch1) + , vec0_node_ptr_(0) + , vec1_node_ptr_(0) + , initialised_ (false) + { + if (is_ivector_node(branch(0))) + { + vector_interface* vi = reinterpret_cast*>(0); + + if (0 != (vi = dynamic_cast*>(branch(0)))) + { + vec0_node_ptr_ = vi->vec(); + vds() = vi->vds(); + } + } + + if (is_ivector_node(branch(1))) + { + vector_interface* vi = reinterpret_cast*>(0); + + if (0 != (vi = dynamic_cast*>(branch(1)))) + { + vec1_node_ptr_ = vi->vec(); + } + } + + if (vec0_node_ptr_ && vec1_node_ptr_) + { + initialised_ = size() <= base_size(); + } + + assert(valid()); + } + + inline T value() const exprtk_override + { + binary_node::branch(0)->value(); + binary_node::branch(1)->value(); + + T* vec0 = vec0_node_ptr_->vds().data(); + T* vec1 = vec1_node_ptr_->vds().data(); + + assert(size() <= base_size()); + const std::size_t n = size(); + + for (std::size_t i = 0; i < n; ++i) + { + std::swap(vec0[i],vec1[i]); + } + + return vec1_node_ptr_->value(); + } + + vector_node_ptr vec() const exprtk_override + { + return vec0_node_ptr_; + } + + vector_node_ptr vec() exprtk_override + { + return vec0_node_ptr_; + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_vecvecswap; + } + + inline bool valid() const exprtk_override + { + return initialised_ && binary_node::valid(); + } + + std::size_t size() const exprtk_override + { + return std::min( + vec0_node_ptr_->vec_holder().size(), + vec1_node_ptr_->vec_holder().size()); + } + + std::size_t base_size() const exprtk_override + { + return std::min( + vec0_node_ptr_->vec_holder().base_size(), + vec1_node_ptr_->vec_holder().base_size()); + } + + vds_t& vds() exprtk_override + { + return vds_; + } + + const vds_t& vds() const exprtk_override + { + return vds_; + } + + private: + + vector_node* vec0_node_ptr_; + vector_node* vec1_node_ptr_; + bool initialised_; + vds_t vds_; + }; + + #ifndef exprtk_disable_string_capabilities + template + class stringvar_node exprtk_final + : public expression_node + , public string_base_node + , public range_interface + { + public: + + typedef typename range_interface::range_t range_t; + + static std::string null_value; + + explicit stringvar_node() + : value_(&null_value) + {} + + explicit stringvar_node(std::string& v) + : value_(&v) + { + rp_.n0_c = std::make_pair(true,0); + rp_.n1_c = std::make_pair(true,v.size()); + rp_.cache.first = rp_.n0_c.second; + rp_.cache.second = rp_.n1_c.second; + } + + inline bool operator <(const stringvar_node& v) const + { + return this < (&v); + } + + inline T value() const exprtk_override + { + rp_.n1_c.second = (*value_).size(); + rp_.cache.second = rp_.n1_c.second; + + return std::numeric_limits::quiet_NaN(); + } + + std::string str() const exprtk_override + { + return ref(); + } + + char_cptr base() const exprtk_override + { + return &(*value_)[0]; + } + + std::size_t size() const exprtk_override + { + return ref().size(); + } + + std::string& ref() + { + return (*value_); + } + + const std::string& ref() const + { + return (*value_); + } + + range_t& range_ref() exprtk_override + { + return rp_; + } + + const range_t& range_ref() const exprtk_override + { + return rp_; + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_stringvar; + } + + void rebase(std::string& s) + { + value_ = &s; + rp_.n0_c = std::make_pair(true,0); + rp_.n1_c = std::make_pair(true,value_->size() - 1); + rp_.cache.first = rp_.n0_c.second; + rp_.cache.second = rp_.n1_c.second; + } + + private: + + std::string* value_; + mutable range_t rp_; + }; + + template + std::string stringvar_node::null_value = std::string(""); + + template + class string_range_node exprtk_final + : public expression_node + , public string_base_node + , public range_interface + { + public: + + typedef typename range_interface::range_t range_t; + + static std::string null_value; + + explicit string_range_node(std::string& v, const range_t& rp) + : value_(&v) + , rp_(rp) + {} + + virtual ~string_range_node() + { + rp_.free(); + } + + inline bool operator <(const string_range_node& v) const + { + return this < (&v); + } + + inline T value() const exprtk_override + { + return std::numeric_limits::quiet_NaN(); + } + + inline std::string str() const exprtk_override + { + return (*value_); + } + + char_cptr base() const exprtk_override + { + return &(*value_)[0]; + } + + std::size_t size() const exprtk_override + { + return ref().size(); + } + + inline range_t range() const + { + return rp_; + } + + inline virtual std::string& ref() + { + return (*value_); + } + + inline virtual const std::string& ref() const + { + return (*value_); + } + + inline range_t& range_ref() exprtk_override + { + return rp_; + } + + inline const range_t& range_ref() const exprtk_override + { + return rp_; + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_stringvarrng; + } + + private: + + std::string* value_; + range_t rp_; + }; + + template + std::string string_range_node::null_value = std::string(""); template class const_string_range_node exprtk_final - : public expression_node , - public string_base_node, - public range_interface + : public expression_node + , public string_base_node + , public range_interface { public: @@ -8527,9 +10374,9 @@ namespace exprtk template class generic_string_range_node exprtk_final - : public expression_node , - public string_base_node, - public range_interface + : public expression_node + , public string_base_node + , public range_interface { public: @@ -8569,8 +10416,7 @@ namespace exprtk } initialised_ = (str_base_ptr_ && str_range_ptr_); - - assert(initialised_); + assert(valid()); } ~generic_string_range_node() @@ -8580,34 +10426,184 @@ namespace exprtk inline T value() const exprtk_override { - if (initialised_) + branch_.first->value(); + + std::size_t str_r0 = 0; + std::size_t str_r1 = 0; + + std::size_t r0 = 0; + std::size_t r1 = 0; + + const range_t& range = str_range_ptr_->range_ref(); + + const std::size_t base_str_size = str_base_ptr_->size(); + + if ( + range (str_r0, str_r1, base_str_size ) && + base_range_(r0 , r1 , base_str_size - str_r0) + ) { - assert(branch_.first); + const std::size_t size = r1 - r0; - branch_.first->value(); + range_.n1_c.second = size; + range_.cache.second = range_.n1_c.second; - std::size_t str_r0 = 0; - std::size_t str_r1 = 0; + value_.assign(str_base_ptr_->base() + str_r0 + r0, size); + } - std::size_t r0 = 0; - std::size_t r1 = 0; + return std::numeric_limits::quiet_NaN(); + } - const range_t& range = str_range_ptr_->range_ref(); + std::string str() const exprtk_override + { + return value_; + } - const std::size_t base_str_size = str_base_ptr_->size(); + char_cptr base() const exprtk_override + { + return &value_[0]; + } - if ( - range (str_r0, str_r1, base_str_size) && - base_range_( r0, r1, base_str_size - str_r0) - ) - { - const std::size_t size = (r1 - r0) + 1; + std::size_t size() const exprtk_override + { + return value_.size(); + } - range_.n1_c.second = size - 1; - range_.cache.second = range_.n1_c.second; + range_t& range_ref() exprtk_override + { + return range_; + } - value_.assign(str_base_ptr_->base() + str_r0 + r0, size); - } + const range_t& range_ref() const exprtk_override + { + return range_; + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_strgenrange; + } + + inline bool valid() const exprtk_override + { + return initialised_ && branch_.first; + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(branch_, node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth(branch_); + } + + private: + + bool initialised_; + branch_t branch_; + str_base_ptr str_base_ptr_; + irange_ptr str_range_ptr_; + mutable range_t base_range_; + mutable range_t range_; + mutable std::string value_; + }; + + template + class string_concat_node exprtk_final + : public binary_node + , public string_base_node + , public range_interface + { + public: + + typedef typename range_interface::range_t range_t; + typedef range_interface irange_t; + typedef irange_t* irange_ptr; + typedef range_t* range_ptr; + typedef expression_node * expression_ptr; + typedef string_base_node* str_base_ptr; + + using binary_node::branch; + + string_concat_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr, branch0, branch1) + , initialised_(false) + , str0_base_ptr_ (0) + , str1_base_ptr_ (0) + , str0_range_ptr_(0) + , str1_range_ptr_(0) + { + range_.n0_c = std::make_pair(true,0); + range_.n1_c = std::make_pair(true,0); + + range_.cache.first = range_.n0_c.second; + range_.cache.second = range_.n1_c.second; + + if (is_generally_string_node(branch(0))) + { + str0_base_ptr_ = dynamic_cast(branch(0)); + + if (0 == str0_base_ptr_) + return; + + str0_range_ptr_ = dynamic_cast(branch(0)); + + if (0 == str0_range_ptr_) + return; + } + + if (is_generally_string_node(branch(1))) + { + str1_base_ptr_ = dynamic_cast(branch(1)); + + if (0 == str1_base_ptr_) + return; + + str1_range_ptr_ = dynamic_cast(branch(1)); + + if (0 == str1_range_ptr_) + return; + } + + initialised_ = str0_base_ptr_ && + str1_base_ptr_ && + str0_range_ptr_ && + str1_range_ptr_ ; + + assert(valid()); + } + + inline T value() const exprtk_override + { + branch(0)->value(); + branch(1)->value(); + + std::size_t str0_r0 = 0; + std::size_t str0_r1 = 0; + + std::size_t str1_r0 = 0; + std::size_t str1_r1 = 0; + + const range_t& range0 = str0_range_ptr_->range_ref(); + const range_t& range1 = str1_range_ptr_->range_ref(); + + if ( + range0(str0_r0, str0_r1, str0_base_ptr_->size()) && + range1(str1_r0, str1_r1, str1_base_ptr_->size()) + ) + { + const std::size_t size0 = (str0_r1 - str0_r0); + const std::size_t size1 = (str1_r1 - str1_r0); + + value_.assign(str0_base_ptr_->base() + str0_r0, size0); + value_.append(str1_base_ptr_->base() + str1_r0, size1); + + range_.n1_c.second = value_.size(); + range_.cache.second = range_.n1_c.second; } return std::numeric_limits::quiet_NaN(); @@ -8640,163 +10636,12 @@ namespace exprtk inline typename expression_node::node_type type() const exprtk_override { - return expression_node::e_strgenrange; - } - - void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override - { - expression_node::ndb_t::collect(branch_, node_delete_list); - } - - std::size_t node_depth() const exprtk_override - { - return expression_node::ndb_t::compute_node_depth(branch_); - } - - private: - - bool initialised_; - branch_t branch_; - str_base_ptr str_base_ptr_; - irange_ptr str_range_ptr_; - mutable range_t base_range_; - mutable range_t range_; - mutable std::string value_; - }; - - template - class string_concat_node exprtk_final - : public binary_node , - public string_base_node, - public range_interface - { - public: - - typedef typename range_interface::range_t range_t; - typedef range_interface irange_t; - typedef irange_t* irange_ptr; - typedef range_t* range_ptr; - typedef expression_node * expression_ptr; - typedef string_base_node* str_base_ptr; - - using binary_node::branch; - - string_concat_node(const operator_type& opr, - expression_ptr branch0, - expression_ptr branch1) - : binary_node(opr, branch0, branch1) - , initialised_(false) - , str0_base_ptr_ (0) - , str1_base_ptr_ (0) - , str0_range_ptr_(0) - , str1_range_ptr_(0) - { - range_.n0_c = std::make_pair(true,0); - range_.n1_c = std::make_pair(true,0); - - range_.cache.first = range_.n0_c.second; - range_.cache.second = range_.n1_c.second; - - if (is_generally_string_node(branch(0))) - { - str0_base_ptr_ = dynamic_cast(branch(0)); - - if (0 == str0_base_ptr_) - return; - - str0_range_ptr_ = dynamic_cast(branch(0)); - - if (0 == str0_range_ptr_) - return; - } - - if (is_generally_string_node(branch(1))) - { - str1_base_ptr_ = dynamic_cast(branch(1)); - - if (0 == str1_base_ptr_) - return; - - str1_range_ptr_ = dynamic_cast(branch(1)); - - if (0 == str1_range_ptr_) - return; - } - - initialised_ = str0_base_ptr_ && - str1_base_ptr_ && - str0_range_ptr_ && - str1_range_ptr_ ; - - assert(initialised_); - } - - inline T value() const exprtk_override - { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); - - branch(0)->value(); - branch(1)->value(); - - std::size_t str0_r0 = 0; - std::size_t str0_r1 = 0; - - std::size_t str1_r0 = 0; - std::size_t str1_r1 = 0; - - const range_t& range0 = str0_range_ptr_->range_ref(); - const range_t& range1 = str1_range_ptr_->range_ref(); - - if ( - range0(str0_r0, str0_r1, str0_base_ptr_->size()) && - range1(str1_r0, str1_r1, str1_base_ptr_->size()) - ) - { - const std::size_t size0 = (str0_r1 - str0_r0) + 1; - const std::size_t size1 = (str1_r1 - str1_r0) + 1; - - value_.assign(str0_base_ptr_->base() + str0_r0, size0); - value_.append(str1_base_ptr_->base() + str1_r0, size1); - - range_.n1_c.second = value_.size() - 1; - range_.cache.second = range_.n1_c.second; - } - } - - return std::numeric_limits::quiet_NaN(); - } - - std::string str() const exprtk_override - { - return value_; - } - - char_cptr base() const exprtk_override - { - return &value_[0]; - } - - std::size_t size() const exprtk_override - { - return value_.size(); - } - - range_t& range_ref() exprtk_override - { - return range_; - } - - const range_t& range_ref() const exprtk_override - { - return range_; + return expression_node::e_strconcat; } - inline typename expression_node::node_type type() const exprtk_override + inline bool valid() const exprtk_override { - return expression_node::e_strconcat; + return initialised_ && binary_node::valid(); } private: @@ -8812,9 +10657,9 @@ namespace exprtk template class swap_string_node exprtk_final - : public binary_node , - public string_base_node, - public range_interface + : public binary_node + , public string_base_node + , public range_interface { public: @@ -8829,10 +10674,10 @@ namespace exprtk using binary_node::branch; swap_string_node(expression_ptr branch0, expression_ptr branch1) - : binary_node(details::e_swap, branch0, branch1), - initialised_(false), - str0_node_ptr_(0), - str1_node_ptr_(0) + : binary_node(details::e_swap, branch0, branch1) + , initialised_(false) + , str0_node_ptr_(0) + , str1_node_ptr_(0) { if (is_string_node(branch(0))) { @@ -8845,22 +10690,15 @@ namespace exprtk } initialised_ = (str0_node_ptr_ && str1_node_ptr_); - - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); - - branch(0)->value(); - branch(1)->value(); + branch(0)->value(); + branch(1)->value(); - std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref()); - } + std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref()); return std::numeric_limits::quiet_NaN(); } @@ -8895,6 +10733,11 @@ namespace exprtk return expression_node::e_strswap; } + inline bool valid() const exprtk_override + { + return initialised_ && binary_node::valid(); + } + private: bool initialised_; @@ -8960,87 +10803,81 @@ namespace exprtk str0_range_ptr_ && str1_range_ptr_ ; - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); + branch(0)->value(); + branch(1)->value(); - branch(0)->value(); - branch(1)->value(); + std::size_t str0_r0 = 0; + std::size_t str0_r1 = 0; - std::size_t str0_r0 = 0; - std::size_t str0_r1 = 0; + std::size_t str1_r0 = 0; + std::size_t str1_r1 = 0; - std::size_t str1_r0 = 0; - std::size_t str1_r1 = 0; + const range_t& range0 = (*str0_range_ptr_); + const range_t& range1 = (*str1_range_ptr_); - const range_t& range0 = (*str0_range_ptr_); - const range_t& range1 = (*str1_range_ptr_); + if ( + range0(str0_r0, str0_r1, str0_base_ptr_->size()) && + range1(str1_r0, str1_r1, str1_base_ptr_->size()) + ) + { + const std::size_t size0 = range0.cache_size(); + const std::size_t size1 = range1.cache_size(); + const std::size_t max_size = std::min(size0,size1); - if ( - range0(str0_r0, str0_r1, str0_base_ptr_->size()) && - range1(str1_r0, str1_r1, str1_base_ptr_->size()) - ) - { - const std::size_t size0 = range0.cache_size(); - const std::size_t size1 = range1.cache_size(); - const std::size_t max_size = std::min(size0,size1); + char_ptr s0 = const_cast(str0_base_ptr_->base() + str0_r0); + char_ptr s1 = const_cast(str1_base_ptr_->base() + str1_r0); - char_ptr s0 = const_cast(str0_base_ptr_->base() + str0_r0); - char_ptr s1 = const_cast(str1_base_ptr_->base() + str1_r0); + loop_unroll::details lud(max_size); + char_cptr upper_bound = s0 + lud.upper_bound; - loop_unroll::details lud(max_size); - char_cptr upper_bound = s0 + lud.upper_bound; + while (s0 < upper_bound) + { + #define exprtk_loop(N) \ + std::swap(s0[N], s1[N]); \ - while (s0 < upper_bound) - { - #define exprtk_loop(N) \ - std::swap(s0[N], s1[N]); \ - - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif - - s0 += lud.batch_size; - s1 += lud.batch_size; - } + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - int i = 0; + s0 += lud.batch_size; + s1 += lud.batch_size; + } - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : { std::swap(s0[i], s1[i]); ++i; } \ - - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + int i = 0; - #undef exprtk_loop - #undef case_stmt + switch (lud.remainder) + { + #define case_stmt(N) \ + case N : { std::swap(s0[i], s1[i]); ++i; } \ + exprtk_fallthrough \ + + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15) case_stmt(14) + case_stmt(13) case_stmt(12) + case_stmt(11) case_stmt(10) + case_stmt( 9) case_stmt( 8) + case_stmt( 7) case_stmt( 6) + case_stmt( 5) case_stmt( 4) + #endif + case_stmt( 3) case_stmt( 2) + case_stmt( 1) + default: break; } + + #undef exprtk_loop + #undef case_stmt } return std::numeric_limits::quiet_NaN(); @@ -9051,6 +10888,11 @@ namespace exprtk return expression_node::e_strswap; } + inline bool valid() const exprtk_override + { + return initialised_ && binary_node::valid(); + } + private: swap_genstrings_node(const swap_genstrings_node&) exprtk_delete; @@ -9068,7 +10910,7 @@ namespace exprtk { public: - static std::string null_value; + static const std::string null_value; explicit stringvar_size_node() : value_(&null_value) @@ -9090,11 +10932,11 @@ namespace exprtk private: - std::string* value_; + const std::string* value_; }; template - std::string stringvar_size_node::null_value = std::string(""); + const std::string stringvar_size_node::null_value = std::string(""); template class string_size_node exprtk_final : public expression_node @@ -9113,23 +10955,15 @@ namespace exprtk if (is_generally_string_node(branch_.first)) { str_base_ptr_ = dynamic_cast(branch_.first); - - if (0 == str_base_ptr_) - return; } + + assert(valid()); } inline T value() const exprtk_override { - T result = std::numeric_limits::quiet_NaN(); - - if (str_base_ptr_) - { - branch_.first->value(); - result = T(str_base_ptr_->size()); - } - - return result; + branch_.first->value(); + return T(str_base_ptr_->size()); } inline typename expression_node::node_type type() const exprtk_override @@ -9137,6 +10971,11 @@ namespace exprtk return expression_node::e_stringsize; } + inline bool valid() const exprtk_override + { + return str_base_ptr_; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(branch_, node_delete_list); @@ -9149,7 +10988,7 @@ namespace exprtk private: - branch_t branch_; + branch_t branch_; str_base_ptr str_base_ptr_; }; @@ -9167,9 +11006,9 @@ namespace exprtk template class assignment_string_node exprtk_final - : public binary_node , - public string_base_node, - public range_interface + : public binary_node + , public string_base_node + , public range_interface { public: @@ -9219,31 +11058,25 @@ namespace exprtk str0_node_ptr_ && str1_range_ptr_ ; - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); + branch(1)->value(); - branch(1)->value(); - - std::size_t r0 = 0; - std::size_t r1 = 0; + std::size_t r0 = 0; + std::size_t r1 = 0; - const range_t& range = (*str1_range_ptr_); + const range_t& range = (*str1_range_ptr_); - if (range(r0, r1, str1_base_ptr_->size())) - { - AssignmentProcess::execute(str0_node_ptr_->ref(), - str1_base_ptr_->base() + r0, - (r1 - r0) + 1); + if (range(r0, r1, str1_base_ptr_->size())) + { + AssignmentProcess::execute( + str0_node_ptr_->ref(), + str1_base_ptr_->base() + r0, (r1 - r0)); - branch(0)->value(); - } + branch(0)->value(); } return std::numeric_limits::quiet_NaN(); @@ -9279,6 +11112,11 @@ namespace exprtk return expression_node::e_strass; } + inline bool valid() const exprtk_override + { + return initialised_ && binary_node::valid(); + } + private: bool initialised_; @@ -9290,9 +11128,9 @@ namespace exprtk template class assignment_string_range_node exprtk_final - : public binary_node , - public string_base_node, - public range_interface + : public binary_node + , public string_base_node + , public range_interface { public: @@ -9351,39 +11189,34 @@ namespace exprtk str0_range_ptr_ && str1_range_ptr_ ; - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); + branch(0)->value(); + branch(1)->value(); - branch(0)->value(); - branch(1)->value(); - - std::size_t s0_r0 = 0; - std::size_t s0_r1 = 0; + std::size_t s0_r0 = 0; + std::size_t s0_r1 = 0; - std::size_t s1_r0 = 0; - std::size_t s1_r1 = 0; + std::size_t s1_r0 = 0; + std::size_t s1_r1 = 0; - const range_t& range0 = (*str0_range_ptr_); - const range_t& range1 = (*str1_range_ptr_); + const range_t& range0 = (*str0_range_ptr_); + const range_t& range1 = (*str1_range_ptr_); - if ( - range0(s0_r0, s0_r1, str0_base_ptr_->size()) && - range1(s1_r0, s1_r1, str1_base_ptr_->size()) - ) - { - const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0)) + 1; + if ( + range0(s0_r0, s0_r1, str0_base_ptr_->size()) && + range1(s1_r0, s1_r1, str1_base_ptr_->size()) + ) + { + const std::size_t size = std::min((s0_r1 - s0_r0), (s1_r1 - s1_r0)); - std::copy(str1_base_ptr_->base() + s1_r0, - str1_base_ptr_->base() + s1_r0 + size, - const_cast(base() + s0_r0)); - } + std::copy( + str1_base_ptr_->base() + s1_r0, + str1_base_ptr_->base() + s1_r0 + size, + const_cast(base() + s0_r0)); } return std::numeric_limits::quiet_NaN(); @@ -9419,6 +11252,11 @@ namespace exprtk return expression_node::e_strass; } + inline bool valid() const exprtk_override + { + return initialised_ && binary_node::valid(); + } + private: bool initialised_; @@ -9431,9 +11269,9 @@ namespace exprtk template class conditional_string_node exprtk_final - : public trinary_node , - public string_base_node, - public range_interface + : public trinary_node + , public string_base_node + , public range_interface { public: @@ -9494,55 +11332,48 @@ namespace exprtk str0_range_ptr_ && str1_range_ptr_ ; - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) + std::size_t r0 = 0; + std::size_t r1 = 0; + + if (is_true(condition_)) { - assert(condition_ ); - assert(consequent_ ); - assert(alternative_); + consequent_->value(); - std::size_t r0 = 0; - std::size_t r1 = 0; + const range_t& range = str0_range_ptr_->range_ref(); - if (is_true(condition_)) + if (range(r0, r1, str0_base_ptr_->size())) { - consequent_->value(); - - const range_t& range = str0_range_ptr_->range_ref(); + const std::size_t size = (r1 - r0); - if (range(r0, r1, str0_base_ptr_->size())) - { - const std::size_t size = (r1 - r0) + 1; + value_.assign(str0_base_ptr_->base() + r0, size); - value_.assign(str0_base_ptr_->base() + r0, size); - - range_.n1_c.second = value_.size() - 1; - range_.cache.second = range_.n1_c.second; + range_.n1_c.second = value_.size(); + range_.cache.second = range_.n1_c.second; - return T(1); - } + return T(1); } - else - { - alternative_->value(); + } + else + { + alternative_->value(); - const range_t& range = str1_range_ptr_->range_ref(); + const range_t& range = str1_range_ptr_->range_ref(); - if (range(r0, r1, str1_base_ptr_->size())) - { - const std::size_t size = (r1 - r0) + 1; + if (range(r0, r1, str1_base_ptr_->size())) + { + const std::size_t size = (r1 - r0); - value_.assign(str1_base_ptr_->base() + r0, size); + value_.assign(str1_base_ptr_->base() + r0, size); - range_.n1_c.second = value_.size() - 1; - range_.cache.second = range_.n1_c.second; + range_.n1_c.second = value_.size(); + range_.cache.second = range_.n1_c.second; - return T(0); - } + return T(0); } } @@ -9579,6 +11410,15 @@ namespace exprtk return expression_node::e_strcondition; } + inline bool valid() const exprtk_override + { + return + initialised_ && + condition_ && condition_ ->valid() && + consequent_ && consequent_ ->valid() && + alternative_&& alternative_->valid() ; + } + private: bool initialised_; @@ -9596,9 +11436,9 @@ namespace exprtk template class cons_conditional_str_node exprtk_final - : public binary_node , - public string_base_node, - public range_interface + : public binary_node + , public string_base_node + , public range_interface { public: @@ -9640,37 +11480,30 @@ namespace exprtk } initialised_ = str0_base_ptr_ && str0_range_ptr_ ; - - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) + if (is_true(condition_)) { - assert(condition_ ); - assert(consequent_); - - if (is_true(condition_)) - { - consequent_->value(); + consequent_->value(); - const range_t& range = str0_range_ptr_->range_ref(); + const range_t& range = str0_range_ptr_->range_ref(); - std::size_t r0 = 0; - std::size_t r1 = 0; + std::size_t r0 = 0; + std::size_t r1 = 0; - if (range(r0, r1, str0_base_ptr_->size())) - { - const std::size_t size = (r1 - r0) + 1; + if (range(r0, r1, str0_base_ptr_->size())) + { + const std::size_t size = (r1 - r0); - value_.assign(str0_base_ptr_->base() + r0, size); + value_.assign(str0_base_ptr_->base() + r0, size); - range_.n1_c.second = value_.size() - 1; - range_.cache.second = range_.n1_c.second; + range_.n1_c.second = value_.size(); + range_.cache.second = range_.n1_c.second; - return T(1); - } + return T(1); } } @@ -9707,6 +11540,14 @@ namespace exprtk return expression_node::e_strccondition; } + inline bool valid() const exprtk_override + { + return + initialised_ && + condition_ && condition_ ->valid() && + consequent_ && consequent_ ->valid() ; + } + private: bool initialised_; @@ -9721,9 +11562,9 @@ namespace exprtk template class str_vararg_node exprtk_final - : public expression_node , - public string_base_node, - public range_interface + : public expression_node + , public string_base_node + , public range_interface { public: @@ -9759,8 +11600,6 @@ namespace exprtk if (0 == str_range_ptr_) return; - initialised_ = str_base_ptr_ && str_range_ptr_; - if (arg_list.size() > 1) { const std::size_t arg_list_size = arg_list.size() - 1; @@ -9769,7 +11608,7 @@ namespace exprtk for (std::size_t i = 0; i < arg_list_size; ++i) { - if (arg_list[i]) + if (arg_list[i] && arg_list[i]->valid()) { construct_branch_pair(arg_list_[i], arg_list[i]); } @@ -9779,7 +11618,12 @@ namespace exprtk return; } } + + initialised_ = true; } + + initialised_ &= str_base_ptr_ && str_range_ptr_; + assert(valid()); } inline T value() const exprtk_override @@ -9824,6 +11668,13 @@ namespace exprtk return expression_node::e_stringvararg; } + inline bool valid() const exprtk_override + { + return + initialised_ && + final_node_.first && final_node_.first->valid(); + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(final_node_ , node_delete_list); @@ -9847,6 +11698,104 @@ namespace exprtk }; #endif + template + class assert_node exprtk_final : public expression_node + { + public: + + typedef expression_node* expression_ptr; + typedef std::pair branch_t; + typedef string_base_node* str_base_ptr; + typedef assert_check::assert_context assert_context_t; + + assert_node(expression_ptr assert_condition_node, + expression_ptr assert_message_node, + assert_check_ptr assert_check, + assert_context_t context) + : assert_message_str_base_(0) + , assert_check_(assert_check) + , context_(context) + { + construct_branch_pair(assert_condition_node_, assert_condition_node); + construct_branch_pair(assert_message_node_ , assert_message_node ); + + #ifndef exprtk_disable_string_capabilities + if ( + assert_message_node_.first && + details::is_generally_string_node(assert_message_node_.first) + ) + { + assert_message_str_base_ = dynamic_cast(assert_message_node_.first); + } + #endif + + assert(valid()); + } + + inline T value() const exprtk_override + { + if (details::is_true(assert_condition_node_.first->value())) + { + return T(1); + } + + #ifndef exprtk_disable_string_capabilities + if (assert_message_node_.first) + { + assert_message_node_.first->value(); + assert(assert_message_str_base_); + context_.message = assert_message_str_base_->str(); + } + #endif + + assert_check_->handle_assert(context_); + return T(0); + } + + inline typename expression_node::node_type type() const exprtk_override + { + return expression_node::e_assert; + } + + inline bool valid() const exprtk_override + { + return ( + assert_check_ && + assert_condition_node_.first && + assert_condition_node_.first->valid() + ) && + ( + (0 == assert_message_node_.first) || + ( + assert_message_node_.first && + assert_message_str_base_ && + assert_message_node_.first->valid() && + details::is_generally_string_node(assert_message_node_.first) + ) + ); + } + + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override + { + expression_node::ndb_t::collect(assert_condition_node_, node_delete_list); + expression_node::ndb_t::collect(assert_message_node_ , node_delete_list); + } + + std::size_t node_depth() const exprtk_override + { + return expression_node::ndb_t::compute_node_depth + (assert_condition_node_, assert_message_node_); + } + + private: + + branch_t assert_condition_node_; + branch_t assert_message_node_; + str_base_ptr assert_message_str_base_; + assert_check_ptr assert_check_; + mutable assert_context_t context_; + }; + template inline T axn(const T a, const T x) { @@ -10087,10 +12036,6 @@ namespace exprtk inline T value() const exprtk_override { - assert(trinary_node::branch_[0].first); - assert(trinary_node::branch_[1].first); - assert(trinary_node::branch_[2].first); - const T x = trinary_node::branch_[0].first->value(); const T y = trinary_node::branch_[1].first->value(); const T z = trinary_node::branch_[2].first->value(); @@ -10116,11 +12061,6 @@ namespace exprtk inline T value() const exprtk_override { - assert(quaternary_node::branch_[0].first); - assert(quaternary_node::branch_[1].first); - assert(quaternary_node::branch_[2].first); - assert(quaternary_node::branch_[3].first); - const T x = quaternary_node::branch_[0].first->value(); const T y = quaternary_node::branch_[1].first->value(); const T z = quaternary_node::branch_[2].first->value(); @@ -10209,12 +12149,13 @@ namespace exprtk template class Sequence> explicit vararg_node(const Sequence& arg_list) + : initialised_(false) { arg_list_.resize(arg_list.size()); for (std::size_t i = 0; i < arg_list.size(); ++i) { - if (arg_list[i]) + if (arg_list[i] && arg_list[i]->valid()) { construct_branch_pair(arg_list_[i],arg_list[i]); } @@ -10224,6 +12165,9 @@ namespace exprtk return; } } + + initialised_ = (arg_list_.size() == arg_list.size()); + assert(valid()); } inline T value() const exprtk_override @@ -10236,6 +12180,11 @@ namespace exprtk return expression_node::e_vararg; } + inline bool valid() const exprtk_override + { + return initialised_; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(arg_list_, node_delete_list); @@ -10246,9 +12195,20 @@ namespace exprtk return expression_node::ndb_t::compute_node_depth(arg_list_); } + std::size_t size() const + { + return arg_list_.size(); + } + + expression_ptr operator[](const std::size_t& index) const + { + return arg_list_[index].first; + } + private: std::vector arg_list_; + bool initialised_; }; template @@ -10261,12 +12221,13 @@ namespace exprtk template class Sequence> explicit vararg_varnode(const Sequence& arg_list) + : initialised_(false) { arg_list_.resize(arg_list.size()); for (std::size_t i = 0; i < arg_list.size(); ++i) { - if (arg_list[i] && is_variable_node(arg_list[i])) + if (arg_list[i] && arg_list[i]->valid() && is_variable_node(arg_list[i])) { variable_node* var_node_ptr = static_cast*>(arg_list[i]); arg_list_[i] = (&var_node_ptr->ref()); @@ -10277,14 +12238,14 @@ namespace exprtk return; } } + + initialised_ = (arg_list.size() == arg_list_.size()); + assert(valid()); } inline T value() const exprtk_override { - if (!arg_list_.empty()) - return VarArgFunction::process(arg_list_); - else - return std::numeric_limits::quiet_NaN(); + return VarArgFunction::process(arg_list_); } inline typename expression_node::node_type type() const exprtk_override @@ -10292,9 +12253,15 @@ namespace exprtk return expression_node::e_vararg; } + inline bool valid() const exprtk_override + { + return initialised_; + } + private: std::vector arg_list_; + bool initialised_; }; template @@ -10314,22 +12281,12 @@ namespace exprtk { ivec_ptr_ = dynamic_cast*>(v_.first); } - else - ivec_ptr_ = 0; } inline T value() const exprtk_override { - if (ivec_ptr_) - { - assert(v_.first); - - v_.first->value(); - - return VecFunction::process(ivec_ptr_); - } - else - return std::numeric_limits::quiet_NaN(); + v_.first->value(); + return VecFunction::process(ivec_ptr_); } inline typename expression_node::node_type type() const exprtk_override @@ -10337,6 +12294,11 @@ namespace exprtk return expression_node::e_vecfunc; } + inline bool valid() const exprtk_override + { + return ivec_ptr_ && v_.first && v_.first->valid(); + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(v_, node_delete_list); @@ -10375,17 +12337,15 @@ namespace exprtk inline T value() const exprtk_override { - if (var_node_ptr_) - { - assert(branch(1)); - - T& result = var_node_ptr_->ref(); + T& result = var_node_ptr_->ref(); result = branch(1)->value(); - return result; - } - else - return std::numeric_limits::quiet_NaN(); + return result; + } + + inline bool valid() const exprtk_override + { + return var_node_ptr_ && binary_node::valid(); } private: @@ -10411,26 +12371,66 @@ namespace exprtk { vec_node_ptr_ = static_cast*>(branch(0)); } + + assert(valid()); } inline T value() const exprtk_override { - if (vec_node_ptr_) + T& result = vec_node_ptr_->ref(); + result = branch(1)->value(); + + return result; + } + + inline bool valid() const exprtk_override + { + return vec_node_ptr_ && binary_node::valid(); + } + + private: + + vector_elem_node* vec_node_ptr_; + }; + + template + class assignment_vec_elem_rtc_node exprtk_final : public binary_node + { + public: + + typedef expression_node* expression_ptr; + using binary_node::branch; + + assignment_vec_elem_rtc_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr, branch0, branch1) + , vec_node_ptr_(0) + { + if (is_vector_elem_rtc_node(branch(0))) { - assert(branch(1)); + vec_node_ptr_ = static_cast*>(branch(0)); + } + + assert(valid()); + } - T& result = vec_node_ptr_->ref(); + inline T value() const exprtk_override + { + T& result = vec_node_ptr_->ref(); result = branch(1)->value(); - return result; - } - else - return std::numeric_limits::quiet_NaN(); + return result; + } + + inline bool valid() const exprtk_override + { + return vec_node_ptr_ && binary_node::valid(); } private: - vector_elem_node* vec_node_ptr_; + vector_elem_rtc_node* vec_node_ptr_; }; template @@ -10451,27 +12451,66 @@ namespace exprtk { rbvec_node_ptr_ = static_cast*>(branch(0)); } + + assert(valid()); } inline T value() const exprtk_override { - if (rbvec_node_ptr_) + T& result = rbvec_node_ptr_->ref(); + result = branch(1)->value(); + + return result; + } + + inline bool valid() const exprtk_override + { + return rbvec_node_ptr_ && binary_node::valid(); + } + + private: + + rebasevector_elem_node* rbvec_node_ptr_; + }; + + template + class assignment_rebasevec_elem_rtc_node exprtk_final : public binary_node + { + public: + + typedef expression_node* expression_ptr; + using expression_node::branch; + + assignment_rebasevec_elem_rtc_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr, branch0, branch1) + , rbvec_node_ptr_(0) + { + if (is_rebasevector_elem_rtc_node(branch(0))) { - assert(branch(1)); + rbvec_node_ptr_ = static_cast*>(branch(0)); + } - T& result = rbvec_node_ptr_->ref(); + assert(valid()); + } + inline T value() const exprtk_override + { + T& result = rbvec_node_ptr_->ref(); result = branch(1)->value(); - return result; - } - else - return std::numeric_limits::quiet_NaN(); + return result; + } + + inline bool valid() const exprtk_override + { + return rbvec_node_ptr_ && binary_node::valid(); } private: - rebasevector_elem_node* rbvec_node_ptr_; + rebasevector_elem_rtc_node* rbvec_node_ptr_; }; template @@ -10492,21 +12531,21 @@ namespace exprtk { rbvec_node_ptr_ = static_cast*>(branch(0)); } + + assert(valid()); } inline T value() const exprtk_override { - if (rbvec_node_ptr_) - { - assert(branch(1)); - - T& result = rbvec_node_ptr_->ref(); + T& result = rbvec_node_ptr_->ref(); result = branch(1)->value(); - return result; - } - else - return std::numeric_limits::quiet_NaN(); + return result; + } + + inline bool valid() const exprtk_override + { + return rbvec_node_ptr_ && binary_node::valid(); } private: @@ -10538,66 +12577,60 @@ namespace exprtk vec_node_ptr_ = static_cast*>(branch(0)); vds() = vec_node_ptr_->vds(); } + + assert(valid()); } inline T value() const exprtk_override { - if (vec_node_ptr_) - { - assert(branch(1)); + const T v = branch(1)->value(); - const T v = branch(1)->value(); + T* vec = vds().data(); - T* vec = vds().data(); - - loop_unroll::details lud(size()); - const T* upper_bound = vec + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec + lud.upper_bound; - while (vec < upper_bound) - { - #define exprtk_loop(N) \ - vec[N] = v; \ + while (vec < upper_bound) + { + #define exprtk_loop(N) \ + vec[N] = v; \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec += lud.batch_size; - } + vec += lud.batch_size; + } - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : *vec++ = v; \ + switch (lud.remainder) + { + #define case_stmt(N) \ + case N : *vec++ = v; \ + exprtk_fallthrough \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15) case_stmt(14) + case_stmt(13) case_stmt(12) + case_stmt(11) case_stmt(10) + case_stmt( 9) case_stmt( 8) + case_stmt( 7) case_stmt( 6) + case_stmt( 5) case_stmt( 4) + #endif + case_stmt( 3) case_stmt( 2) + case 1 : *vec++ = v; + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return vec_node_ptr_->value(); - } - else - return std::numeric_limits::quiet_NaN(); + return vec_node_ptr_->value(); } vector_node_ptr vec() const exprtk_override @@ -10615,9 +12648,22 @@ namespace exprtk return expression_node::e_vecvalass; } + inline bool valid() const exprtk_override + { + return + vec_node_ptr_ && + (vds().size() <= vec_node_ptr_->vec_holder().base_size()) && + binary_node::valid(); + } + std::size_t size() const exprtk_override { - return vds().size(); + return vec_node_ptr_->vec_holder().size(); + } + + std::size_t base_size() const exprtk_override + { + return vec_node_ptr_->vec_holder().base_size(); } vds_t& vds() exprtk_override @@ -10687,74 +12733,71 @@ namespace exprtk } } - initialised_ = (vec0_node_ptr_ && vec1_node_ptr_); + initialised_ = + vec0_node_ptr_ && + vec1_node_ptr_ && + (size() <= base_size()) && + (vds_.size() <= base_size()) && + binary_node::valid(); - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(1)); + branch(1)->value(); - branch(1)->value(); - - if (src_is_ivec_) - return vec0_node_ptr_->value(); + if (src_is_ivec_) + return vec0_node_ptr_->value(); - T* vec0 = vec0_node_ptr_->vds().data(); - T* vec1 = vec1_node_ptr_->vds().data(); + T* vec0 = vec0_node_ptr_->vds().data(); + T* vec1 = vec1_node_ptr_->vds().data(); - loop_unroll::details lud(size()); - const T* upper_bound = vec0 + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec0 + lud.upper_bound; - while (vec0 < upper_bound) - { - #define exprtk_loop(N) \ - vec0[N] = vec1[N]; \ + while (vec0 < upper_bound) + { + #define exprtk_loop(N) \ + vec0[N] = vec1[N]; \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec0 += lud.batch_size; - vec1 += lud.batch_size; - } + vec0 += lud.batch_size; + vec1 += lud.batch_size; + } - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : *vec0++ = *vec1++; \ + switch (lud.remainder) + { + #define case_stmt(N,fall_through) \ + case N : *vec0++ = *vec1++; \ + fall_through \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) + case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) + case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) + case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) + case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) + case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) + #endif + case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) + case_stmt( 1, (void)0;) + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return vec0_node_ptr_->value(); - } - else - return std::numeric_limits::quiet_NaN(); + return vec0_node_ptr_->value(); } vector_node_ptr vec() exprtk_override @@ -10772,9 +12815,23 @@ namespace exprtk return expression_node::e_vecvecass; } + inline bool valid() const exprtk_override + { + return initialised_; + } + std::size_t size() const exprtk_override { - return vds().size(); + return std::min( + vec0_node_ptr_->vec_holder().size(), + vec1_node_ptr_->vec_holder().size()); + } + + std::size_t base_size() const exprtk_override + { + return std::min( + vec0_node_ptr_->vec_holder().base_size(), + vec1_node_ptr_->vec_holder().base_size()); } vds_t& vds() exprtk_override @@ -10814,21 +12871,21 @@ namespace exprtk { var_node_ptr_ = static_cast*>(branch(0)); } + + assert(valid()); } inline T value() const exprtk_override { - if (var_node_ptr_) - { - assert(branch(1)); + T& v = var_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); - T& v = var_node_ptr_->ref(); - v = Operation::process(v,branch(1)->value()); + return v; + } - return v; - } - else - return std::numeric_limits::quiet_NaN(); + inline bool valid() const exprtk_override + { + return var_node_ptr_ && binary_node::valid(); } private: @@ -10854,26 +12911,106 @@ namespace exprtk { vec_node_ptr_ = static_cast*>(branch(0)); } + + assert(valid()); } inline T value() const exprtk_override { - if (vec_node_ptr_) + T& v = vec_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); + + return v; + } + + inline bool valid() const exprtk_override + { + return vec_node_ptr_ && binary_node::valid(); + } + + private: + + vector_elem_node* vec_node_ptr_; + }; + + template + class assignment_vec_elem_op_rtc_node exprtk_final : public binary_node + { + public: + + typedef expression_node* expression_ptr; + using binary_node::branch; + + assignment_vec_elem_op_rtc_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr, branch0, branch1) + , vec_node_ptr_(0) + { + if (is_vector_elem_rtc_node(branch(0))) { - assert(branch(1)); + vec_node_ptr_ = static_cast*>(branch(0)); + } + + assert(valid()); + } + + inline T value() const exprtk_override + { + T& v = vec_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); + + return v; + } + + inline bool valid() const exprtk_override + { + return vec_node_ptr_ && binary_node::valid(); + } + + private: + + vector_elem_rtc_node* vec_node_ptr_; + }; + + template + class assignment_vec_celem_op_rtc_node exprtk_final : public binary_node + { + public: - T& v = vec_node_ptr_->ref(); - v = Operation::process(v,branch(1)->value()); + typedef expression_node* expression_ptr; + using binary_node::branch; - return v; + assignment_vec_celem_op_rtc_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr, branch0, branch1) + , vec_node_ptr_(0) + { + if (is_vector_celem_rtc_node(branch(0))) + { + vec_node_ptr_ = static_cast*>(branch(0)); } - else - return std::numeric_limits::quiet_NaN(); + + assert(valid()); + } + + inline T value() const exprtk_override + { + T& v = vec_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); + + return v; + } + + inline bool valid() const exprtk_override + { + return vec_node_ptr_ && binary_node::valid(); } private: - vector_elem_node* vec_node_ptr_; + vector_celem_rtc_node* vec_node_ptr_; }; template @@ -10894,21 +13031,21 @@ namespace exprtk { rbvec_node_ptr_ = static_cast*>(branch(0)); } + + assert(valid()); } inline T value() const exprtk_override { - if (rbvec_node_ptr_) - { - assert(branch(1)); + T& v = rbvec_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); - T& v = rbvec_node_ptr_->ref(); - v = Operation::process(v,branch(1)->value()); + return v; + } - return v; - } - else - return std::numeric_limits::quiet_NaN(); + inline bool valid() const exprtk_override + { + return rbvec_node_ptr_ && binary_node::valid(); } private: @@ -10934,26 +13071,106 @@ namespace exprtk { rbvec_node_ptr_ = static_cast*>(branch(0)); } + + assert(valid()); } inline T value() const exprtk_override { - if (rbvec_node_ptr_) + T& v = rbvec_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); + + return v; + } + + inline bool valid() const exprtk_override + { + return rbvec_node_ptr_ && binary_node::valid(); + } + + private: + + rebasevector_celem_node* rbvec_node_ptr_; + }; + + template + class assignment_rebasevec_elem_op_rtc_node exprtk_final : public binary_node + { + public: + + typedef expression_node* expression_ptr; + using binary_node::branch; + + assignment_rebasevec_elem_op_rtc_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr, branch0, branch1) + , rbvec_node_ptr_(0) + { + if (is_rebasevector_elem_rtc_node(branch(0))) { - assert(branch(1)); + rbvec_node_ptr_ = static_cast*>(branch(0)); + } + + assert(valid()); + } + + inline T value() const exprtk_override + { + T& v = rbvec_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); + + return v; + } + + inline bool valid() const exprtk_override + { + return rbvec_node_ptr_ && binary_node::valid(); + } - T& v = rbvec_node_ptr_->ref(); - v = Operation::process(v,branch(1)->value()); + private: + + rebasevector_elem_rtc_node* rbvec_node_ptr_; + }; + + template + class assignment_rebasevec_celem_op_rtc_node exprtk_final : public binary_node + { + public: + + typedef expression_node* expression_ptr; + using binary_node::branch; - return v; + assignment_rebasevec_celem_op_rtc_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr, branch0, branch1) + , rbvec_node_ptr_(0) + { + if (is_rebasevector_celem_rtc_node(branch(0))) + { + rbvec_node_ptr_ = static_cast*>(branch(0)); } - else - return std::numeric_limits::quiet_NaN(); + + assert(valid()); + } + + inline T value() const exprtk_override + { + T& v = rbvec_node_ptr_->ref(); + v = Operation::process(v,branch(1)->value()); + + return v; + } + + inline bool valid() const exprtk_override + { + return rbvec_node_ptr_ && binary_node::valid(); } private: - rebasevector_celem_node* rbvec_node_ptr_; + rebasevector_celem_rtc_node* rbvec_node_ptr_; }; template @@ -10980,66 +13197,60 @@ namespace exprtk vec_node_ptr_ = static_cast*>(branch(0)); vds() = vec_node_ptr_->vds(); } + + assert(valid()); } inline T value() const exprtk_override { - if (vec_node_ptr_) - { - assert(branch(1)); - - const T v = branch(1)->value(); + const T v = branch(1)->value(); - T* vec = vds().data(); + T* vec = vds().data(); - loop_unroll::details lud(size()); - const T* upper_bound = vec + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec + lud.upper_bound; - while (vec < upper_bound) - { - #define exprtk_loop(N) \ - Operation::assign(vec[N],v); \ + while (vec < upper_bound) + { + #define exprtk_loop(N) \ + Operation::assign(vec[N],v); \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec += lud.batch_size; - } + vec += lud.batch_size; + } - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : Operation::assign(*vec++,v); \ + switch (lud.remainder) + { + #define case_stmt(N,fall_through) \ + case N : Operation::assign(*vec++,v); \ + fall_through \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) + case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) + case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) + case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) + case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) + case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) + #endif + case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) + case_stmt( 1, (void)0;) + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return vec_node_ptr_->value(); - } - else - return std::numeric_limits::quiet_NaN(); + return vec_node_ptr_->value(); } vector_node_ptr vec() const exprtk_override @@ -11057,9 +13268,22 @@ namespace exprtk return expression_node::e_vecopvalass; } + inline bool valid() const exprtk_override + { + return + vec_node_ptr_ && + (size() <= base_size()) && + binary_node::valid() ; + } + std::size_t size() const exprtk_override { - return vds().size(); + return vec_node_ptr_->vec_holder().size(); + } + + std::size_t base_size() const exprtk_override + { + return vec_node_ptr_->vec_holder().base_size(); } vds_t& vds() exprtk_override @@ -11122,81 +13346,76 @@ namespace exprtk if (0 != (vi = dynamic_cast*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); - vec1_node_ptr_->vds() = vds(); + vec1_node_ptr_->vds() = vi->vds(); } else vds_t::match_sizes(vds(),vec1_node_ptr_->vds()); } - initialised_ = (vec0_node_ptr_ && vec1_node_ptr_); + initialised_ = + vec0_node_ptr_ && + vec1_node_ptr_ && + (size() <= base_size()) && + binary_node::valid(); - assert(initialised_); + assert(valid()); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); - - branch(0)->value(); - branch(1)->value(); + branch(0)->value(); + branch(1)->value(); - T* vec0 = vec0_node_ptr_->vds().data(); - const T* vec1 = vec1_node_ptr_->vds().data(); + T* vec0 = vec0_node_ptr_->vds().data(); + const T* vec1 = vec1_node_ptr_->vds().data(); - loop_unroll::details lud(size()); - const T* upper_bound = vec0 + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec0 + lud.upper_bound; - while (vec0 < upper_bound) - { - #define exprtk_loop(N) \ - vec0[N] = Operation::process(vec0[N], vec1[N]); \ + while (vec0 < upper_bound) + { + #define exprtk_loop(N) \ + vec0[N] = Operation::process(vec0[N], vec1[N]); \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec0 += lud.batch_size; - vec1 += lud.batch_size; - } + vec0 += lud.batch_size; + vec1 += lud.batch_size; + } - int i = 0; + int i = 0; - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ + switch (lud.remainder) + { + #define case_stmt(N,fall_through) \ + case N : { vec0[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ + fall_through \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) + case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) + case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) + case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) + case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) + case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) + #endif + case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) + case_stmt( 1, (void)0;) + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return vec0_node_ptr_->value(); - } - else - return std::numeric_limits::quiet_NaN(); + return vec0_node_ptr_->value(); } vector_node_ptr vec() const exprtk_override @@ -11214,9 +13433,23 @@ namespace exprtk return expression_node::e_vecopvecass; } + inline bool valid() const exprtk_override + { + return initialised_; + } + std::size_t size() const exprtk_override { - return vds().size(); + return std::min( + vec0_node_ptr_->vec_holder().size(), + vec1_node_ptr_->vec_holder().size()); + } + + std::size_t base_size() const exprtk_override + { + return std::min( + vec0_node_ptr_->vec_holder().base_size(), + vec1_node_ptr_->vec_holder().base_size()); } vds_t& vds() exprtk_override @@ -11242,6 +13475,64 @@ namespace exprtk vds_t vds_; }; + template + struct memory_context_t + { + typedef vector_node* vector_node_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; + + memory_context_t() + : temp_(0) + , temp_vec_node_(0) + {} + + void clear() + { + delete temp_vec_node_; + delete temp_; + } + + vector_holder_ptr temp_; + vector_node_ptr temp_vec_node_; + }; + + template + inline memory_context_t make_memory_context(vector_holder& vec_holder, + vec_data_store& vds) + { + memory_context_t result_ctxt; + result_ctxt.temp_ = (vec_holder.rebaseable()) ? + new vector_holder(vec_holder,vds) : + new vector_holder(vds) ; + result_ctxt.temp_vec_node_ = new vector_node (vds,result_ctxt.temp_); + return result_ctxt; + } + + template + inline memory_context_t make_memory_context(vector_holder& vec_holder0, + vector_holder& vec_holder1, + vec_data_store& vds) + { + memory_context_t result_ctxt; + + if (!vec_holder0.rebaseable() && !vec_holder1.rebaseable()) + result_ctxt.temp_ = new vector_holder(vds); + else if (vec_holder0.rebaseable() && !vec_holder1.rebaseable()) + result_ctxt.temp_ = new vector_holder(vec_holder0,vds); + else if (!vec_holder0.rebaseable() && vec_holder1.rebaseable()) + result_ctxt.temp_ = new vector_holder(vec_holder1,vds); + else + { + result_ctxt.temp_ = (vec_holder0.base_size() >= vec_holder1.base_size()) ? + new vector_holder(vec_holder0, vds) : + new vector_holder(vec_holder1, vds) ; + } + + result_ctxt.temp_vec_node_ = new vector_node (vds,result_ctxt.temp_); + return result_ctxt; + } + template class vec_binop_vecvec_node exprtk_final : public binary_node @@ -11251,8 +13542,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - typedef vector_holder* vector_holder_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; typedef vec_data_store vds_t; + typedef memory_context_t memory_context; using binary_node::branch; @@ -11262,8 +13555,6 @@ namespace exprtk : binary_node(opr, branch0, branch1) , vec0_node_ptr_(0) , vec1_node_ptr_(0) - , temp_ (0) - , temp_vec_node_(0) , initialised_(false) { bool v0_is_ivec = false; @@ -11304,104 +13595,102 @@ namespace exprtk vector_holder& vec0 = vec0_node_ptr_->vec_holder(); vector_holder& vec1 = vec1_node_ptr_->vec_holder(); - if (v0_is_ivec && (vec0.size() <= vec1.size())) + if (v0_is_ivec && (vec0.base_size() <= vec1.base_size())) + { vds_ = vds_t(vec0_node_ptr_->vds()); - else if (v1_is_ivec && (vec1.size() <= vec0.size())) + } + else if (v1_is_ivec && (vec1.base_size() <= vec0.base_size())) + { vds_ = vds_t(vec1_node_ptr_->vds()); + } else - vds_ = vds_t(std::min(vec0.size(),vec1.size())); + { + vds_ = vds_t(std::min(vec0.base_size(),vec1.base_size())); + } - temp_ = new vector_holder(vds().data(),vds().size()); - temp_vec_node_ = new vector_node (vds(),temp_); + memory_context_ = make_memory_context(vec0, vec1, vds()); - initialised_ = true; + initialised_ = + (size() <= base_size()) && + binary_node::valid(); } - assert(initialised_); + assert(valid()); } ~vec_binop_vecvec_node() { - delete temp_; - delete temp_vec_node_; + memory_context_.clear(); } inline T value() const exprtk_override { - if (initialised_) - { - assert(branch(0)); - assert(branch(1)); - - branch(0)->value(); - branch(1)->value(); + branch(0)->value(); + branch(1)->value(); - const T* vec0 = vec0_node_ptr_->vds().data(); - const T* vec1 = vec1_node_ptr_->vds().data(); - T* vec2 = vds().data(); + const T* vec0 = vec0_node_ptr_->vds().data(); + const T* vec1 = vec1_node_ptr_->vds().data(); + T* vec2 = vds().data(); - loop_unroll::details lud(size()); - const T* upper_bound = vec2 + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec2 + lud.upper_bound; - while (vec2 < upper_bound) - { - #define exprtk_loop(N) \ - vec2[N] = Operation::process(vec0[N], vec1[N]); \ + while (vec2 < upper_bound) + { + #define exprtk_loop(N) \ + vec2[N] = Operation::process(vec0[N], vec1[N]); \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec0 += lud.batch_size; - vec1 += lud.batch_size; - vec2 += lud.batch_size; - } + vec0 += lud.batch_size; + vec1 += lud.batch_size; + vec2 += lud.batch_size; + } - int i = 0; + int i = 0; - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ + switch (lud.remainder) + { + #define case_stmt(N) \ + case N : { vec2[i] = Operation::process(vec0[i], vec1[i]); ++i; } \ + exprtk_fallthrough \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15) case_stmt(14) + case_stmt(13) case_stmt(12) + case_stmt(11) case_stmt(10) + case_stmt( 9) case_stmt( 8) + case_stmt( 7) case_stmt( 6) + case_stmt( 5) case_stmt( 4) + #endif + case_stmt( 3) case_stmt( 2) + case_stmt( 1) + default: break; + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return (vds().data())[0]; - } - else - return std::numeric_limits::quiet_NaN(); + return (vds().data())[0]; } vector_node_ptr vec() const exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } vector_node_ptr vec() exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } inline typename expression_node::node_type type() const exprtk_override @@ -11409,9 +13698,23 @@ namespace exprtk return expression_node::e_vecvecarith; } + inline bool valid() const exprtk_override + { + return initialised_; + } + std::size_t size() const exprtk_override { - return vds_.size(); + return std::min( + vec0_node_ptr_->vec_holder().size(), + vec1_node_ptr_->vec_holder().size()); + } + + std::size_t base_size() const exprtk_override + { + return std::min( + vec0_node_ptr_->vec_holder().base_size(), + vec1_node_ptr_->vec_holder().base_size()); } vds_t& vds() exprtk_override @@ -11426,12 +13729,11 @@ namespace exprtk private: - vector_node_ptr vec0_node_ptr_; - vector_node_ptr vec1_node_ptr_; - vector_holder_ptr temp_; - vector_node_ptr temp_vec_node_; - bool initialised_; - vds_t vds_; + vector_node_ptr vec0_node_ptr_; + vector_node_ptr vec1_node_ptr_; + bool initialised_; + vds_t vds_; + memory_context memory_context_; }; template @@ -11443,8 +13745,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - typedef vector_holder* vector_holder_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; typedef vec_data_store vds_t; + typedef memory_context_t memory_context; using binary_node::branch; @@ -11453,8 +13757,6 @@ namespace exprtk expression_ptr branch1) : binary_node(opr, branch0, branch1) , vec0_node_ptr_(0) - , temp_ (0) - , temp_vec_node_(0) { bool v0_is_ivec = false; @@ -11478,93 +13780,84 @@ namespace exprtk if (v0_is_ivec) vds() = vec0_node_ptr_->vds(); else - vds() = vds_t(vec0_node_ptr_->size()); + vds() = vds_t(vec0_node_ptr_->base_size()); - temp_ = new vector_holder(vds()); - temp_vec_node_ = new vector_node (vds(),temp_); + memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds()); } + + assert(valid()); } ~vec_binop_vecval_node() { - delete temp_; - delete temp_vec_node_; + memory_context_.clear(); } inline T value() const exprtk_override { - if (vec0_node_ptr_) - { - assert(branch(0)); - assert(branch(1)); - - branch(0)->value(); - const T v = branch(1)->value(); + branch(0)->value(); + const T v = branch(1)->value(); - const T* vec0 = vec0_node_ptr_->vds().data(); - T* vec1 = vds().data(); + const T* vec0 = vec0_node_ptr_->vds().data(); + T* vec1 = vds().data(); - loop_unroll::details lud(size()); - const T* upper_bound = vec0 + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec0 + lud.upper_bound; - while (vec0 < upper_bound) - { - #define exprtk_loop(N) \ - vec1[N] = Operation::process(vec0[N], v); \ + while (vec0 < upper_bound) + { + #define exprtk_loop(N) \ + vec1[N] = Operation::process(vec0[N], v); \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec0 += lud.batch_size; - vec1 += lud.batch_size; - } + vec0 += lud.batch_size; + vec1 += lud.batch_size; + } - int i = 0; + int i = 0; - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \ + switch (lud.remainder) + { + #define case_stmt(N,fall_through) \ + case N : { vec1[i] = Operation::process(vec0[i], v); ++i; } \ + fall_through \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) + case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) + case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) + case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) + case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) + case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) + #endif + case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) + case_stmt( 1, (void)0;) + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return (vds().data())[0]; - } - else - return std::numeric_limits::quiet_NaN(); + return (vds().data())[0]; } vector_node_ptr vec() const exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } vector_node_ptr vec() exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } inline typename expression_node::node_type type() const exprtk_override @@ -11572,9 +13865,22 @@ namespace exprtk return expression_node::e_vecvalarith; } + inline bool valid() const exprtk_override + { + return + vec0_node_ptr_ && + (size() <= base_size()) && + binary_node::valid(); + } + std::size_t size() const exprtk_override { - return vds().size(); + return vec0_node_ptr_->size(); + } + + std::size_t base_size() const exprtk_override + { + return vec0_node_ptr_->vec_holder().base_size(); } vds_t& vds() exprtk_override @@ -11590,9 +13896,8 @@ namespace exprtk private: vector_node_ptr vec0_node_ptr_; - vector_holder_ptr temp_; - vector_node_ptr temp_vec_node_; vds_t vds_; + memory_context memory_context_; }; template @@ -11604,8 +13909,10 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - typedef vector_holder* vector_holder_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; typedef vec_data_store vds_t; + typedef memory_context_t memory_context; using binary_node::branch; @@ -11614,8 +13921,6 @@ namespace exprtk expression_ptr branch1) : binary_node(opr, branch0, branch1) , vec1_node_ptr_(0) - , temp_ (0) - , temp_vec_node_(0) { bool v1_is_ivec = false; @@ -11639,93 +13944,84 @@ namespace exprtk if (v1_is_ivec) vds() = vec1_node_ptr_->vds(); else - vds() = vds_t(vec1_node_ptr_->size()); + vds() = vds_t(vec1_node_ptr_->base_size()); - temp_ = new vector_holder(vds()); - temp_vec_node_ = new vector_node (vds(),temp_); + memory_context_ = make_memory_context(vec1_node_ptr_->vec_holder(), vds()); } + + assert(valid()); } ~vec_binop_valvec_node() { - delete temp_; - delete temp_vec_node_; + memory_context_.clear(); } inline T value() const exprtk_override { - if (vec1_node_ptr_) - { - assert(branch(0)); - assert(branch(1)); - - const T v = branch(0)->value(); - branch(1)->value(); + const T v = branch(0)->value(); + branch(1)->value(); - T* vec0 = vds().data(); - const T* vec1 = vec1_node_ptr_->vds().data(); + T* vec0 = vds().data(); + const T* vec1 = vec1_node_ptr_->vds().data(); - loop_unroll::details lud(size()); - const T* upper_bound = vec0 + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec0 + lud.upper_bound; - while (vec0 < upper_bound) - { - #define exprtk_loop(N) \ - vec0[N] = Operation::process(v, vec1[N]); \ + while (vec0 < upper_bound) + { + #define exprtk_loop(N) \ + vec0[N] = Operation::process(v, vec1[N]); \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec0 += lud.batch_size; - vec1 += lud.batch_size; - } + vec0 += lud.batch_size; + vec1 += lud.batch_size; + } - int i = 0; + int i = 0; - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \ + switch (lud.remainder) + { + #define case_stmt(N,fall_through) \ + case N : { vec0[i] = Operation::process(v, vec1[i]); ++i; } \ + fall_through \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) + case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) + case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) + case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) + case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) + case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) + #endif + case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) + case_stmt( 1, (void)0;) + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return (vds().data())[0]; - } - else - return std::numeric_limits::quiet_NaN(); + return (vds().data())[0]; } vector_node_ptr vec() const exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } vector_node_ptr vec() exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } inline typename expression_node::node_type type() const exprtk_override @@ -11733,9 +14029,23 @@ namespace exprtk return expression_node::e_vecvalarith; } + inline bool valid() const exprtk_override + { + return + vec1_node_ptr_ && + (size() <= base_size()) && + (vds_.size() <= base_size()) && + binary_node::valid(); + } + std::size_t size() const exprtk_override { - return vds().size(); + return vec1_node_ptr_->vec_holder().size(); + } + + std::size_t base_size() const exprtk_override + { + return vec1_node_ptr_->vec_holder().base_size(); } vds_t& vds() exprtk_override @@ -11751,9 +14061,8 @@ namespace exprtk private: vector_node_ptr vec1_node_ptr_; - vector_holder_ptr temp_; - vector_node_ptr temp_vec_node_; vds_t vds_; + memory_context memory_context_; }; template @@ -11765,28 +14074,28 @@ namespace exprtk typedef expression_node* expression_ptr; typedef vector_node* vector_node_ptr; - typedef vector_holder* vector_holder_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; typedef vec_data_store vds_t; + typedef memory_context_t memory_context; using expression_node::branch; unary_vector_node(const operator_type& opr, expression_ptr branch0) : unary_node(opr, branch0) , vec0_node_ptr_(0) - , temp_ (0) - , temp_vec_node_(0) { bool vec0_is_ivec = false; - if (is_vector_node(branch())) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast(branch()); + vec0_node_ptr_ = static_cast(branch(0)); } - else if (is_ivector_node(branch())) + else if (is_ivector_node(branch(0))) { vector_interface* vi = reinterpret_cast*>(0); - if (0 != (vi = dynamic_cast*>(branch()))) + if (0 != (vi = dynamic_cast*>(branch(0)))) { vec0_node_ptr_ = vi->vec(); vec0_is_ivec = true; @@ -11798,91 +14107,84 @@ namespace exprtk if (vec0_is_ivec) vds_ = vec0_node_ptr_->vds(); else - vds_ = vds_t(vec0_node_ptr_->size()); + vds_ = vds_t(vec0_node_ptr_->base_size()); - temp_ = new vector_holder(vds()); - temp_vec_node_ = new vector_node (vds(),temp_); + memory_context_ = make_memory_context(vec0_node_ptr_->vec_holder(), vds()); } + + assert(valid()); } ~unary_vector_node() { - delete temp_; - delete temp_vec_node_; + memory_context_.clear(); } inline T value() const exprtk_override { - assert(branch()); - branch()->value(); - if (vec0_node_ptr_) - { - const T* vec0 = vec0_node_ptr_->vds().data(); - T* vec1 = vds().data(); + const T* vec0 = vec0_node_ptr_->vds().data(); + T* vec1 = vds().data(); - loop_unroll::details lud(size()); - const T* upper_bound = vec0 + lud.upper_bound; + loop_unroll::details lud(size()); + const T* upper_bound = vec0 + lud.upper_bound; - while (vec0 < upper_bound) - { - #define exprtk_loop(N) \ - vec1[N] = Operation::process(vec0[N]); \ + while (vec0 < upper_bound) + { + #define exprtk_loop(N) \ + vec1[N] = Operation::process(vec0[N]); \ - exprtk_loop( 0) exprtk_loop( 1) - exprtk_loop( 2) exprtk_loop( 3) - #ifndef exprtk_disable_superscalar_unroll - exprtk_loop( 4) exprtk_loop( 5) - exprtk_loop( 6) exprtk_loop( 7) - exprtk_loop( 8) exprtk_loop( 9) - exprtk_loop(10) exprtk_loop(11) - exprtk_loop(12) exprtk_loop(13) - exprtk_loop(14) exprtk_loop(15) - #endif + exprtk_loop( 0) exprtk_loop( 1) + exprtk_loop( 2) exprtk_loop( 3) + #ifndef exprtk_disable_superscalar_unroll + exprtk_loop( 4) exprtk_loop( 5) + exprtk_loop( 6) exprtk_loop( 7) + exprtk_loop( 8) exprtk_loop( 9) + exprtk_loop(10) exprtk_loop(11) + exprtk_loop(12) exprtk_loop(13) + exprtk_loop(14) exprtk_loop(15) + #endif - vec0 += lud.batch_size; - vec1 += lud.batch_size; - } + vec0 += lud.batch_size; + vec1 += lud.batch_size; + } - int i = 0; + int i = 0; - exprtk_disable_fallthrough_begin - switch (lud.remainder) - { - #define case_stmt(N) \ - case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \ + switch (lud.remainder) + { + #define case_stmt(N) \ + case N : { vec1[i] = Operation::process(vec0[i]); ++i; } \ + exprtk_fallthrough \ - #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) - #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) - } - exprtk_disable_fallthrough_end + #ifndef exprtk_disable_superscalar_unroll + case_stmt(15) case_stmt(14) + case_stmt(13) case_stmt(12) + case_stmt(11) case_stmt(10) + case_stmt( 9) case_stmt( 8) + case_stmt( 7) case_stmt( 6) + case_stmt( 5) case_stmt( 4) + #endif + case_stmt( 3) case_stmt( 2) + case_stmt( 1) + default: break; + } - #undef exprtk_loop - #undef case_stmt + #undef exprtk_loop + #undef case_stmt - return (vds().data())[0]; - } - else - return std::numeric_limits::quiet_NaN(); + return (vds().data())[0]; } vector_node_ptr vec() const exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } vector_node_ptr vec() exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } inline typename expression_node::node_type type() const exprtk_override @@ -11890,9 +14192,19 @@ namespace exprtk return expression_node::e_vecunaryop; } + inline bool valid() const exprtk_override + { + return vec0_node_ptr_ && unary_node::valid(); + } + std::size_t size() const exprtk_override { - return vds().size(); + return vec0_node_ptr_->vec_holder().size(); + } + + std::size_t base_size() const exprtk_override + { + return vec0_node_ptr_->vec_holder().base_size(); } vds_t& vds() exprtk_override @@ -11907,10 +14219,9 @@ namespace exprtk private: - vector_node_ptr vec0_node_ptr_; - vector_holder_ptr temp_; - vector_node_ptr temp_vec_node_; - vds_t vds_; + vector_node_ptr vec0_node_ptr_; + vds_t vds_; + memory_context memory_context_; }; template @@ -11923,8 +14234,10 @@ namespace exprtk typedef expression_node * expression_ptr; typedef vector_interface* vec_interface_ptr; typedef vector_node * vector_node_ptr; - typedef vector_holder * vector_holder_ptr; + typedef vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; typedef vec_data_store vds_t; + typedef memory_context_t memory_context; typedef std::pair branch_t; conditional_vector_node(expression_ptr condition, @@ -11934,7 +14247,7 @@ namespace exprtk , alternative_node_ptr_(0) , temp_vec_node_ (0) , temp_ (0) - , vec_size_ (0) + , result_vec_size_ (0) , initialised_ (false) { construct_branch_pair(condition_ , condition ); @@ -11963,67 +14276,62 @@ namespace exprtk if (consequent_node_ptr_ && alternative_node_ptr_) { - vec_size_ = std::min(consequent_node_ptr_ ->vds().size(), - alternative_node_ptr_->vds().size()); + const std::size_t vec_size = + std::max(consequent_node_ptr_ ->vec_holder().base_size(), + alternative_node_ptr_->vec_holder().base_size()); - vds_ = vds_t(vec_size_); - temp_ = new vector_holder(vds_); - temp_vec_node_ = new vector_node (vds(),temp_); + vds_ = vds_t(vec_size); + memory_context_ = make_memory_context( + consequent_node_ptr_ ->vec_holder(), + alternative_node_ptr_->vec_holder(), + vds()); - initialised_ = true; + initialised_ = (vec_size > 0); } - assert(initialised_ && (vec_size_ > 0)); + assert(initialised_); } ~conditional_vector_node() { - delete temp_; - delete temp_vec_node_; + memory_context_.clear(); } inline T value() const exprtk_override { - if (initialised_) - { - assert(condition_ .first); - assert(consequent_ .first); - assert(alternative_.first); - - T result = T(0); - T* source_vector = 0; - T* result_vector = vds().data(); - - if (is_true(condition_)) - { - result = consequent_.first->value(); - source_vector = consequent_node_ptr_->vds().data(); - } - else - { - result = alternative_.first->value(); - source_vector = alternative_node_ptr_->vds().data(); - } + T result = T(0); + T* source_vector = 0; + T* result_vector = vds().data(); - for (std::size_t i = 0; i < vec_size_; ++i) - { - result_vector[i] = source_vector[i]; - } + if (is_true(condition_)) + { + result = consequent_.first->value(); + source_vector = consequent_node_ptr_->vds().data(); + result_vec_size_ = consequent_node_ptr_->size(); + } + else + { + result = alternative_.first->value(); + source_vector = alternative_node_ptr_->vds().data(); + result_vec_size_ = alternative_node_ptr_->size(); + } - return result; + for (std::size_t i = 0; i < result_vec_size_; ++i) + { + result_vector[i] = source_vector[i]; } - return std::numeric_limits::quiet_NaN(); + return result; } vector_node_ptr vec() const exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } vector_node_ptr vec() exprtk_override { - return temp_vec_node_; + return memory_context_.temp_vec_node_; } inline typename expression_node::node_type type() const exprtk_override @@ -12031,9 +14339,26 @@ namespace exprtk return expression_node::e_vecondition; } + inline bool valid() const exprtk_override + { + return + initialised_ && + condition_ .first && condition_ .first->valid() && + consequent_ .first && consequent_ .first->valid() && + alternative_.first && alternative_.first->valid() && + size() <= base_size(); + } + std::size_t size() const exprtk_override { - return vec_size_; + return result_vec_size_; + } + + std::size_t base_size() const exprtk_override + { + return std::min( + consequent_node_ptr_ ->vec_holder().base_size(), + alternative_node_ptr_->vec_holder().base_size()); } vds_t& vds() exprtk_override @@ -12061,16 +14386,17 @@ namespace exprtk private: - branch_t condition_; - branch_t consequent_; - branch_t alternative_; - vector_node_ptr consequent_node_ptr_; - vector_node_ptr alternative_node_ptr_; - vector_node_ptr temp_vec_node_; - vector_holder_ptr temp_; - vds_t vds_; - std::size_t vec_size_; - bool initialised_; + branch_t condition_; + branch_t consequent_; + branch_t alternative_; + vector_node_ptr consequent_node_ptr_; + vector_node_ptr alternative_node_ptr_; + vector_node_ptr temp_vec_node_; + vector_holder_ptr temp_; + vds_t vds_; + mutable std::size_t result_vec_size_; + bool initialised_; + memory_context memory_context_; }; template @@ -12085,13 +14411,12 @@ namespace exprtk expression_ptr branch0, expression_ptr branch1) : binary_node(opr, branch0, branch1) - {} + { + assert(binary_node::valid()); + } inline T value() const exprtk_override { - assert(branch(0)); - assert(branch(1)); - return ( std::not_equal_to() (T(0),branch(0)->value()) && @@ -12113,13 +14438,12 @@ namespace exprtk expression_ptr branch0, expression_ptr branch1) : binary_node(opr, branch0, branch1) - {} + { + assert(binary_node::valid()); + } inline T value() const exprtk_override { - assert(branch(0)); - assert(branch(1)); - return ( std::not_equal_to() (T(0),branch(0)->value()) || @@ -12134,7 +14458,7 @@ namespace exprtk { public: - // Function of N paramters. + // Function of N parameters. typedef expression_node* expression_ptr; typedef std::pair branch_t; typedef IFunction ifunction; @@ -12142,6 +14466,7 @@ namespace exprtk explicit function_N_node(ifunction* func) : function_((N == func->param_count) ? func : reinterpret_cast(0)) , parameter_count_(func->param_count) + , initialised_(false) {} template @@ -12152,19 +14477,24 @@ namespace exprtk #pragma warning(push) #pragma warning(disable: 4127) #endif + if (N != NumBranches) + { return false; - else + } + + for (std::size_t i = 0; i < NumBranches; ++i) { - for (std::size_t i = 0; i < NumBranches; ++i) - { - if (b[i]) - branch_[i] = std::make_pair(b[i],branch_deletable(b[i])); - else - return false; - } - return true; + if (b[i] && b[i]->valid()) + branch_[i] = std::make_pair(b[i],branch_deletable(b[i])); + else + return false; } + + initialised_ = function_; + assert(valid()); + return initialised_; + #ifdef _MSC_VER #pragma warning(pop) #endif @@ -12182,14 +14512,11 @@ namespace exprtk #pragma warning(push) #pragma warning(disable: 4127) #endif - if ((0 == function_) || (0 == N)) - return std::numeric_limits::quiet_NaN(); - else - { - T v[N]; - evaluate_branches::execute(v,branch_); - return invoke::execute(*function_,v); - } + + T v[N]; + evaluate_branches::execute(v,branch_); + return invoke::execute(*function_,v); + #ifdef _MSC_VER #pragma warning(pop) #endif @@ -12200,9 +14527,14 @@ namespace exprtk return expression_node::e_function; } + inline bool valid() const exprtk_override + { + return initialised_; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override @@ -12222,6 +14554,20 @@ namespace exprtk } }; + template + struct evaluate_branches + { + static inline void execute(T_ (&v)[6], const branch_t (&b)[6]) + { + v[0] = b[0].first->value(); + v[1] = b[1].first->value(); + v[2] = b[2].first->value(); + v[3] = b[3].first->value(); + v[4] = b[4].first->value(); + v[5] = b[5].first->value(); + } + }; + template struct evaluate_branches { @@ -12425,6 +14771,7 @@ namespace exprtk ifunction* function_; std::size_t parameter_count_; branch_t branch_[N]; + bool initialised_; }; template @@ -12437,7 +14784,9 @@ namespace exprtk explicit function_N_node(ifunction* func) : function_((0 == func->param_count) ? func : reinterpret_cast(0)) - {} + { + assert(valid()); + } inline bool operator <(const function_N_node& fn) const { @@ -12446,10 +14795,7 @@ namespace exprtk inline T value() const exprtk_override { - if (function_) - return (*function_)(); - else - return std::numeric_limits::quiet_NaN(); + return (*function_)(); } inline typename expression_node::node_type type() const exprtk_override @@ -12457,6 +14803,11 @@ namespace exprtk return expression_node::e_function; } + inline bool valid() const exprtk_override + { + return function_; + } + private: ifunction* function_; @@ -12475,6 +14826,7 @@ namespace exprtk , arg_list_(arg_list) { value_list_.resize(arg_list.size(),std::numeric_limits::quiet_NaN()); + assert(valid()); } inline bool operator <(const vararg_function_node& fn) const @@ -12484,13 +14836,8 @@ namespace exprtk inline T value() const exprtk_override { - if (function_) - { - populate_value_list(); - return (*function_)(value_list_); - } - else - return std::numeric_limits::quiet_NaN(); + populate_value_list(); + return (*function_)(value_list_); } inline typename expression_node::node_type type() const exprtk_override @@ -12498,6 +14845,11 @@ namespace exprtk return expression_node::e_vafunction; } + inline bool valid() const exprtk_override + { + return function_; + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { for (std::size_t i = 0; i < arg_list_.size(); ++i) @@ -12545,7 +14897,8 @@ namespace exprtk typedef typename range_interface::range_t range_t; typedef std::pair branch_t; - typedef std::pair void_t; + typedef vector_holder* vh_t; + typedef vector_view* vecview_t; typedef std::vector tmp_vs_t; typedef std::vector typestore_list_t; @@ -12557,7 +14910,18 @@ namespace exprtk , arg_list_(arg_list) {} - virtual ~generic_function_node() {} + virtual ~generic_function_node() + { + for (std::size_t i = 0; i < vv_list_.size(); ++i) + { + vecview_t& vv = vv_list_[i]; + if (vv && typestore_list_[i].vec_data) + { + vv->remove_ref(&typestore_list_[i].vec_data); + typestore_list_[i].vec_data = 0; + } + } + } void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { @@ -12571,10 +14935,11 @@ namespace exprtk virtual bool init_branches() { - expr_as_vec1_store_.resize(arg_list_.size(),T(0) ); - typestore_list_ .resize(arg_list_.size(),type_store_t() ); - range_list_ .resize(arg_list_.size(),range_data_type_t()); - branch_ .resize(arg_list_.size(),branch_t(reinterpret_cast(0),false)); + expr_as_vec1_store_.resize(arg_list_.size(), T(0) ); + typestore_list_ .resize(arg_list_.size(), type_store_t() ); + range_list_ .resize(arg_list_.size(), range_data_type_t()); + branch_ .resize(arg_list_.size(), branch_t(reinterpret_cast(0),false)); + vv_list_ .resize(arg_list_.size(), vecview_t(0)); for (std::size_t i = 0; i < arg_list_.size(); ++i) { @@ -12592,7 +14957,15 @@ namespace exprtk ts.size = vi->size(); ts.data = vi->vds().data(); ts.type = type_store_t::e_vector; - vi->vec()->vec_holder().set_ref(&ts.vec_data); + + if ( + vi->vec()->vec_holder().rebaseable() && + vi->vec()->vec_holder().rebaseable_instance() + ) + { + vv_list_[i] = vi->vec()->vec_holder().rebaseable_instance(); + vv_list_[i]->set_ref(&ts.vec_data); + } } #ifndef exprtk_disable_string_capabilities else if (is_generally_string_node(arg_list_[i])) @@ -12628,7 +15001,10 @@ namespace exprtk range_list_[i].range = reinterpret_cast(0); } else + { range_list_[i].range = &(ri->range_ref()); + range_param_list_.push_back(i); + } } #endif else if (is_variable_node(arg_list_[i])) @@ -12662,14 +15038,11 @@ namespace exprtk inline T value() const exprtk_override { - if (function_) + if (populate_value_list()) { - if (populate_value_list()) - { - typedef typename GenericFunction::parameter_list_t parameter_list_t; + typedef typename GenericFunction::parameter_list_t parameter_list_t; - return (*function_)(parameter_list_t(typestore_list_)); - } + return (*function_)(parameter_list_t(typestore_list_)); } return std::numeric_limits::quiet_NaN(); @@ -12680,6 +15053,11 @@ namespace exprtk return expression_node::e_genfunction; } + inline bool valid() const exprtk_override + { + return function_; + } + protected: inline virtual bool populate_value_list() const @@ -12689,30 +15067,40 @@ namespace exprtk expr_as_vec1_store_[i] = branch_[i].first->value(); } - for (std::size_t i = 0; i < branch_.size(); ++i) + if (!range_param_list_.empty()) { - range_data_type_t& rdt = range_list_[i]; + assert(range_param_list_.size() <= branch_.size()); - if (rdt.range) + for (std::size_t i = 0; i < range_param_list_.size(); ++i) { + const std::size_t index = range_param_list_[i]; + range_data_type_t& rdt = range_list_[index]; + const range_t& rp = (*rdt.range); std::size_t r0 = 0; std::size_t r1 = 0; - if (rp(r0, r1, rdt.size)) - { - type_store_t& ts = typestore_list_[i]; + const std::size_t data_size = + #ifndef exprtk_disable_string_capabilities + rdt.str_node ? rdt.str_node->size() : rdt.size; + #else + rdt.size; + #endif - ts.size = rp.cache_size(); - #ifndef exprtk_disable_string_capabilities - if (ts.type == type_store_t::e_string) - ts.data = const_cast(rdt.str_node->base()) + rp.cache.first; - else - #endif - ts.data = static_cast(rdt.data) + (rp.cache.first * rdt.type_size); + if (!rp(r0, r1, data_size)) + { + return false; } + + type_store_t& ts = typestore_list_[index]; + + ts.size = rp.cache_size(); + #ifndef exprtk_disable_string_capabilities + if (ts.type == type_store_t::e_string) + ts.data = const_cast(rdt.str_node->base()) + rp.cache.first; else - return false; + #endif + ts.data = static_cast(rdt.data) + (rp.cache.first * rdt.type_size); } } @@ -12725,16 +15113,18 @@ namespace exprtk private: std::vector arg_list_; - std::vector branch_; - mutable tmp_vs_t expr_as_vec1_store_; - mutable range_list_t range_list_; + std::vector branch_; + std::vector vv_list_; + mutable tmp_vs_t expr_as_vec1_store_; + mutable range_list_t range_list_; + std::vector range_param_list_; }; #ifndef exprtk_disable_string_capabilities template - class string_function_node : public generic_function_node, - public string_base_node, - public range_interface + class string_function_node : public generic_function_node + , public string_base_node + , public range_interface { public: @@ -12749,6 +15139,7 @@ namespace exprtk range_.n1_c = std::make_pair(true,0); range_.cache.first = range_.n0_c.second; range_.cache.second = range_.n1_c.second; + assert(valid()); } inline bool operator <(const string_function_node& fn) const @@ -12758,23 +15149,21 @@ namespace exprtk inline T value() const exprtk_override { - if (gen_function_t::function_) + if (gen_function_t::populate_value_list()) { - if (gen_function_t::populate_value_list()) - { - typedef typename StringFunction::parameter_list_t parameter_list_t; + typedef typename StringFunction::parameter_list_t parameter_list_t; - const T result = (*gen_function_t::function_) - ( - ret_string_, - parameter_list_t(gen_function_t::typestore_list_) - ); + const T result = + (*gen_function_t::function_) + ( + ret_string_, + parameter_list_t(gen_function_t::typestore_list_) + ); - range_.n1_c.second = ret_string_.size() - 1; - range_.cache.second = range_.n1_c.second; + range_.n1_c.second = ret_string_.size(); + range_.cache.second = range_.n1_c.second; - return result; - } + return result; } return std::numeric_limits::quiet_NaN(); @@ -12785,6 +15174,11 @@ namespace exprtk return expression_node::e_strfunction; } + inline bool valid() const exprtk_override + { + return gen_function_t::function_; + } + std::string str() const exprtk_override { return ret_string_; @@ -12834,18 +15228,18 @@ namespace exprtk inline T value() const exprtk_override { - if (gen_function_t::function_) + assert(gen_function_t::valid()); + + if (gen_function_t::populate_value_list()) { - if (gen_function_t::populate_value_list()) - { - typedef typename GenericFunction::parameter_list_t parameter_list_t; + typedef typename GenericFunction::parameter_list_t parameter_list_t; - return (*gen_function_t::function_) - ( - param_seq_index_, - parameter_list_t(gen_function_t::typestore_list_) - ); - } + return + (*gen_function_t::function_) + ( + param_seq_index_, + parameter_list_t(gen_function_t::typestore_list_) + ); } return std::numeric_limits::quiet_NaN(); @@ -12879,24 +15273,22 @@ namespace exprtk inline T value() const exprtk_override { - if (str_function_t::function_) + if (str_function_t::populate_value_list()) { - if (str_function_t::populate_value_list()) - { - typedef typename StringFunction::parameter_list_t parameter_list_t; + typedef typename StringFunction::parameter_list_t parameter_list_t; - const T result = (*str_function_t::function_) - ( - param_seq_index_, - str_function_t::ret_string_, - parameter_list_t(str_function_t::typestore_list_) - ); + const T result = + (*str_function_t::function_) + ( + param_seq_index_, + str_function_t::ret_string_, + parameter_list_t(str_function_t::typestore_list_) + ); - str_function_t::range_.n1_c.second = str_function_t::ret_string_.size() - 1; - str_function_t::range_.cache.second = str_function_t::range_.n1_c.second; + str_function_t::range_.n1_c.second = str_function_t::ret_string_.size(); + str_function_t::range_.cache.second = str_function_t::range_.n1_c.second; - return result; - } + return result; } return std::numeric_limits::quiet_NaN(); @@ -12913,15 +15305,15 @@ namespace exprtk }; #endif - class return_exception - {}; + class return_exception {}; template class null_igenfunc { public: - virtual ~null_igenfunc() {} + virtual ~null_igenfunc() + {} typedef type_store generic_type; typedef typename generic_type::parameter_list parameter_list_t; @@ -12947,14 +15339,13 @@ namespace exprtk results_context_t& rc) : gen_function_t (arg_list) , results_context_(&rc) - {} + { + assert(valid()); + } inline T value() const exprtk_override { - if ( - (0 != results_context_) && - gen_function_t::populate_value_list() - ) + if (gen_function_t::populate_value_list()) { typedef typename type_store::parameter_list parameter_list_t; @@ -12972,6 +15363,11 @@ namespace exprtk return expression_node::e_return; } + inline bool valid() const exprtk_override + { + return results_context_; + } + private: results_context_t* results_context_; @@ -12991,12 +15387,11 @@ namespace exprtk , return_invoked_ (false) { construct_branch_pair(body_, body); + assert(valid()); } inline T value() const exprtk_override { - assert(body_.first); - try { return_invoked_ = false; @@ -13007,6 +15402,7 @@ namespace exprtk catch(const return_exception&) { return_invoked_ = true; + return std::numeric_limits::quiet_NaN(); } } @@ -13016,6 +15412,11 @@ namespace exprtk return expression_node::e_retenv; } + inline bool valid() const exprtk_override + { + return results_context_ && body_.first; + } + inline bool* retinvk_ptr() { return &return_invoked_; @@ -13400,7 +15801,7 @@ namespace exprtk } template - struct vararg_add_op : public opr_base + struct vararg_add_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13423,7 +15824,7 @@ namespace exprtk for (std::size_t i = 0; i < arg_list.size(); ++i) { - result += value(arg_list[i]); + result += value(arg_list[i]); } return result; @@ -13467,7 +15868,7 @@ namespace exprtk }; template - struct vararg_mul_op : public opr_base + struct vararg_mul_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13534,7 +15935,7 @@ namespace exprtk }; template - struct vararg_avg_op : public opr_base + struct vararg_avg_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13590,7 +15991,7 @@ namespace exprtk }; template - struct vararg_min_op : public opr_base + struct vararg_min_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13661,7 +16062,7 @@ namespace exprtk }; template - struct vararg_max_op : public opr_base + struct vararg_max_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13732,7 +16133,7 @@ namespace exprtk }; template - struct vararg_mand_op : public opr_base + struct vararg_mand_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13812,7 +16213,7 @@ namespace exprtk }; template - struct vararg_mor_op : public opr_base + struct vararg_mor_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13892,7 +16293,7 @@ namespace exprtk }; template - struct vararg_multi_op : public opr_base + struct vararg_multi_op exprtk_final : public opr_base { typedef typename opr_base::Type Type; @@ -13913,14 +16314,13 @@ namespace exprtk case 7 : return process_7(arg_list); case 8 : return process_8(arg_list); default : - { - for (std::size_t i = 0; i < (arg_list.size() - 1); ++i) - { - value(arg_list[i]); - } - - return value(arg_list.back()); - } + { + for (std::size_t i = 0; i < (arg_list.size() - 1); ++i) + { + value(arg_list[i]); + } + return value(arg_list.back()); + } } } @@ -14009,7 +16409,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { const T* vec = v->vec()->vds().data(); - const std::size_t vec_size = v->vec()->vds().size(); + const std::size_t vec_size = v->size(); loop_unroll::details lud(vec_size); @@ -14018,24 +16418,24 @@ namespace exprtk T result = T(0); int i = 0; - exprtk_disable_fallthrough_begin switch (vec_size) { - #define case_stmt(N) \ - case N : result += vec[i++]; \ + #define case_stmt(N,fall_through) \ + case N : result += vec[i++]; \ + fall_through \ #ifndef exprtk_disable_superscalar_unroll - case_stmt(16) case_stmt(15) - case_stmt(14) case_stmt(13) - case_stmt(12) case_stmt(11) - case_stmt(10) case_stmt( 9) - case_stmt( 8) case_stmt( 7) - case_stmt( 6) case_stmt( 5) + case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough) + case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough) + case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough) + case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough) + case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough) + case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough) + #endif - case_stmt( 4) case_stmt( 3) - case_stmt( 2) case_stmt( 1) + case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough) + case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;) } - exprtk_disable_fallthrough_end #undef case_stmt @@ -14070,24 +16470,23 @@ namespace exprtk int i = 0; - exprtk_disable_fallthrough_begin switch (lud.remainder) { - #define case_stmt(N) \ - case N : r[0] += vec[i++]; \ + #define case_stmt(N,fall_through) \ + case N : r[0] += vec[i++]; \ + fall_through \ #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) + case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) + case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) + case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) + case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) + case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) + case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) + case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) + case_stmt( 1, (void)0;) } - exprtk_disable_fallthrough_end #undef exprtk_loop #undef case_stmt @@ -14110,7 +16509,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { const T* vec = v->vec()->vds().data(); - const std::size_t vec_size = v->vec()->vds().size(); + const std::size_t vec_size = v->vec()->size(); loop_unroll::details lud(vec_size); @@ -14119,24 +16518,23 @@ namespace exprtk T result = T(1); int i = 0; - exprtk_disable_fallthrough_begin switch (vec_size) { - #define case_stmt(N) \ - case N : result *= vec[i++]; \ + #define case_stmt(N,fall_through) \ + case N : result *= vec[i++]; \ + fall_through \ #ifndef exprtk_disable_superscalar_unroll - case_stmt(16) case_stmt(15) - case_stmt(14) case_stmt(13) - case_stmt(12) case_stmt(11) - case_stmt(10) case_stmt( 9) - case_stmt( 8) case_stmt( 7) - case_stmt( 6) case_stmt( 5) + case_stmt(16, exprtk_fallthrough) case_stmt(15, exprtk_fallthrough) + case_stmt(14, exprtk_fallthrough) case_stmt(13, exprtk_fallthrough) + case_stmt(12, exprtk_fallthrough) case_stmt(11, exprtk_fallthrough) + case_stmt(10, exprtk_fallthrough) case_stmt( 9, exprtk_fallthrough) + case_stmt( 8, exprtk_fallthrough) case_stmt( 7, exprtk_fallthrough) + case_stmt( 6, exprtk_fallthrough) case_stmt( 5, exprtk_fallthrough) #endif - case_stmt( 4) case_stmt( 3) - case_stmt( 2) case_stmt( 1) + case_stmt( 4, exprtk_fallthrough) case_stmt( 3, exprtk_fallthrough) + case_stmt( 2, exprtk_fallthrough) case_stmt( 1, (void)0;) } - exprtk_disable_fallthrough_end #undef case_stmt @@ -14171,33 +16569,32 @@ namespace exprtk int i = 0; - exprtk_disable_fallthrough_begin switch (lud.remainder) { - #define case_stmt(N) \ - case N : r[0] *= vec[i++]; \ + #define case_stmt(N,fall_through) \ + case N : r[0] *= vec[i++]; \ + fall_through \ #ifndef exprtk_disable_superscalar_unroll - case_stmt(15) case_stmt(14) - case_stmt(13) case_stmt(12) - case_stmt(11) case_stmt(10) - case_stmt( 9) case_stmt( 8) - case_stmt( 7) case_stmt( 6) - case_stmt( 5) case_stmt( 4) + case_stmt(15, exprtk_fallthrough) case_stmt(14, exprtk_fallthrough) + case_stmt(13, exprtk_fallthrough) case_stmt(12, exprtk_fallthrough) + case_stmt(11, exprtk_fallthrough) case_stmt(10, exprtk_fallthrough) + case_stmt( 9, exprtk_fallthrough) case_stmt( 8, exprtk_fallthrough) + case_stmt( 7, exprtk_fallthrough) case_stmt( 6, exprtk_fallthrough) + case_stmt( 5, exprtk_fallthrough) case_stmt( 4, exprtk_fallthrough) #endif - case_stmt( 3) case_stmt( 2) - case_stmt( 1) + case_stmt( 3, exprtk_fallthrough) case_stmt( 2, exprtk_fallthrough) + case_stmt( 1, (void)0;) } - exprtk_disable_fallthrough_end #undef exprtk_loop #undef case_stmt return (r[ 0] * r[ 1] * r[ 2] * r[ 3]) #ifndef exprtk_disable_superscalar_unroll - + (r[ 4] * r[ 5] * r[ 6] * r[ 7]) - + (r[ 8] * r[ 9] * r[10] * r[11]) - + (r[12] * r[13] * r[14] * r[15]) + * (r[ 4] * r[ 5] * r[ 6] * r[ 7]) + * (r[ 8] * r[ 9] * r[10] * r[11]) + * (r[12] * r[13] * r[14] * r[15]) #endif ; } @@ -14210,7 +16607,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { - const T vec_size = T(v->vec()->vds().size()); + const T vec_size = T(v->vec()->size()); return vec_add_op::process(v) / vec_size; } }; @@ -14223,7 +16620,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { const T* vec = v->vec()->vds().data(); - const std::size_t vec_size = v->vec()->vds().size(); + const std::size_t vec_size = v->vec()->size(); T result = vec[0]; @@ -14247,7 +16644,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { const T* vec = v->vec()->vds().data(); - const std::size_t vec_size = v->vec()->vds().size(); + const std::size_t vec_size = v->vec()->size(); T result = vec[0]; @@ -14268,7 +16665,8 @@ namespace exprtk { public: - virtual ~vov_base_node() {} + virtual ~vov_base_node() + {} inline virtual operator_type operation() const { @@ -14285,7 +16683,8 @@ namespace exprtk { public: - virtual ~cov_base_node() {} + virtual ~cov_base_node() + {} inline virtual operator_type operation() const { @@ -14302,7 +16701,8 @@ namespace exprtk { public: - virtual ~voc_base_node() {} + virtual ~voc_base_node() + {} inline virtual operator_type operation() const { @@ -14319,7 +16719,8 @@ namespace exprtk { public: - virtual ~vob_base_node() {} + virtual ~vob_base_node() + {} virtual const T& v() const = 0; }; @@ -14329,7 +16730,8 @@ namespace exprtk { public: - virtual ~bov_base_node() {} + virtual ~bov_base_node() + {} virtual const T& v() const = 0; }; @@ -14339,7 +16741,8 @@ namespace exprtk { public: - virtual ~cob_base_node() {} + virtual ~cob_base_node() + {} inline virtual operator_type operation() const { @@ -14358,7 +16761,8 @@ namespace exprtk { public: - virtual ~boc_base_node() {} + virtual ~boc_base_node() + {} inline virtual operator_type operation() const { @@ -14377,7 +16781,8 @@ namespace exprtk { public: - virtual ~uv_base_node() {} + virtual ~uv_base_node() + {} inline virtual operator_type operation() const { @@ -14392,7 +16797,8 @@ namespace exprtk { public: - virtual ~sos_base_node() {} + virtual ~sos_base_node() + {} inline virtual operator_type operation() const { @@ -14405,7 +16811,8 @@ namespace exprtk { public: - virtual ~sosos_base_node() {} + virtual ~sosos_base_node() + {} inline virtual operator_type operation() const { @@ -14418,7 +16825,8 @@ namespace exprtk { public: - virtual ~T0oT1oT2_base_node() {} + virtual ~T0oT1oT2_base_node() + {} virtual std::string type_id() const = 0; }; @@ -14428,7 +16836,8 @@ namespace exprtk { public: - virtual ~T0oT1oT2oT3_base_node() {} + virtual ~T0oT1oT2oT3_base_node() + {} virtual std::string type_id() const = 0; }; @@ -14564,6 +16973,11 @@ namespace exprtk return Operation::type(); } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + inline operator_type operation() { return Operation::operation(); @@ -15186,7 +17600,8 @@ namespace exprtk { public: - virtual ~sf3ext_type_node() {} + virtual ~sf3ext_type_node() + {} virtual T0 t0() const = 0; @@ -15644,16 +18059,16 @@ namespace exprtk typedef std::pair branch_t; typedef Operation operation_t; - // variable op constant node + // variable op binary node explicit vob_node(const T& var, const expression_ptr branch) : v_(var) { construct_branch_pair(branch_, branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); return Operation::process(v_,branch_.first->value()); } @@ -15662,6 +18077,11 @@ namespace exprtk return v_; } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + inline expression_node* branch(const std::size_t&) const exprtk_override { return branch_.first; @@ -15669,7 +18089,7 @@ namespace exprtk void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override @@ -15695,16 +18115,16 @@ namespace exprtk typedef std::pair branch_t; typedef Operation operation_t; - // variable op constant node + // binary node op variable node explicit bov_node(const expression_ptr branch, const T& var) : v_(var) { construct_branch_pair(branch_, branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); return Operation::process(branch_.first->value(),v_); } @@ -15713,6 +18133,11 @@ namespace exprtk return v_; } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + inline expression_node* branch(const std::size_t&) const exprtk_override { return branch_.first; @@ -15720,7 +18145,7 @@ namespace exprtk void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override @@ -15746,16 +18171,16 @@ namespace exprtk typedef std::pair branch_t; typedef Operation operation_t; - // variable op constant node + // constant op variable node explicit cob_node(const T const_var, const expression_ptr branch) : c_(const_var) { construct_branch_pair(branch_, branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); return Operation::process(c_,branch_.first->value()); } @@ -15774,6 +18199,11 @@ namespace exprtk (*const_cast(&c_)) = new_c; } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + inline expression_node* branch(const std::size_t&) const exprtk_override { return branch_.first; @@ -15787,7 +18217,7 @@ namespace exprtk void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override @@ -15813,16 +18243,16 @@ namespace exprtk typedef std::pair branch_t; typedef Operation operation_t; - // variable op constant node + // binary node op constant node explicit boc_node(const expression_ptr branch, const T const_var) : c_(const_var) { construct_branch_pair(branch_, branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); return Operation::process(branch_.first->value(),c_); } @@ -15841,6 +18271,11 @@ namespace exprtk (*const_cast(&c_)) = new_c; } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + inline expression_node* branch(const std::size_t&) const exprtk_override { return branch_.first; @@ -15854,7 +18289,7 @@ namespace exprtk void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override @@ -16013,7 +18448,13 @@ namespace exprtk std::size_t r1 = 0; if (rp1_(r0, r1, s1_.size())) - return Operation::process(s0_, s1_.substr(r0, (r1 - r0) + 1)); + { + return Operation::process + ( + s0_, + s1_.substr(r0, (r1 - r0) + 1) + ); + } else return T(0); } @@ -16085,10 +18526,11 @@ namespace exprtk rp1_(r0_1, r1_1, s1_.size()) ) { - return Operation::process( - s0_.substr(r0_0, (r1_0 - r0_0) + 1), - s1_.substr(r0_1, (r1_1 - r0_1) + 1) - ); + return Operation::process + ( + s0_.substr(r0_0, (r1_0 - r0_0) + 1), + s1_.substr(r0_1, (r1_1 - r0_1) + 1) + ); } else return T(0); @@ -16149,6 +18591,7 @@ namespace exprtk , str1_base_ptr_ (0) , str0_range_ptr_(0) , str1_range_ptr_(0) + , initialised_ (false) { if (is_generally_string_node(branch(0))) { @@ -16179,39 +18622,40 @@ namespace exprtk str1_range_ptr_ = &(range->range_ref()); } + + initialised_ = + str0_base_ptr_ && + str1_base_ptr_ && + str0_range_ptr_ && + str1_range_ptr_; + + assert(valid()); } inline T value() const exprtk_override { - if ( - str0_base_ptr_ && - str1_base_ptr_ && - str0_range_ptr_ && - str1_range_ptr_ - ) - { - branch(0)->value(); - branch(1)->value(); + branch(0)->value(); + branch(1)->value(); - std::size_t str0_r0 = 0; - std::size_t str0_r1 = 0; + std::size_t str0_r0 = 0; + std::size_t str0_r1 = 0; - std::size_t str1_r0 = 0; - std::size_t str1_r1 = 0; + std::size_t str1_r0 = 0; + std::size_t str1_r1 = 0; - const range_t& range0 = (*str0_range_ptr_); - const range_t& range1 = (*str1_range_ptr_); + const range_t& range0 = (*str0_range_ptr_); + const range_t& range1 = (*str1_range_ptr_); - if ( - range0(str0_r0, str0_r1, str0_base_ptr_->size()) && - range1(str1_r0, str1_r1, str1_base_ptr_->size()) - ) - { - return Operation::process( - str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0) + 1), - str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0) + 1) - ); - } + if ( + range0(str0_r0, str0_r1, str0_base_ptr_->size()) && + range1(str1_r0, str1_r1, str1_base_ptr_->size()) + ) + { + return Operation::process + ( + str0_base_ptr_->str().substr(str0_r0,(str0_r1 - str0_r0)), + str1_base_ptr_->str().substr(str1_r0,(str1_r1 - str1_r0)) + ); } return std::numeric_limits::quiet_NaN(); @@ -16222,6 +18666,11 @@ namespace exprtk return Operation::type(); } + inline bool valid() const exprtk_override + { + return initialised_; + } + private: str_sogens_node(const str_sogens_node&) exprtk_delete; @@ -16231,6 +18680,7 @@ namespace exprtk str_base_ptr str1_base_ptr_; range_ptr str0_range_ptr_; range_ptr str1_range_ptr_; + bool initialised_; }; template @@ -16242,7 +18692,7 @@ namespace exprtk typedef Operation operation_t; typedef sosos_node node_type; - // variable op variable node + // string op string op string node explicit sosos_node(SType0 p0, SType1 p1, SType2 p2) : s0_(p0) , s1_(p1) @@ -16334,11 +18784,11 @@ namespace exprtk explicit bipow_node(expression_ptr branch) { construct_branch_pair(branch_, branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); return PowOp::result(branch_.first->value()); } @@ -16347,6 +18797,11 @@ namespace exprtk return expression_node::e_ipow; } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { expression_node::ndb_t::collect(branch_, node_delete_list); @@ -16396,7 +18851,7 @@ namespace exprtk }; template - class bipowninv_node exprtk_final : public expression_node + class bipowinv_node exprtk_final : public expression_node { public: @@ -16404,14 +18859,14 @@ namespace exprtk typedef std::pair branch_t; typedef PowOp operation_t; - explicit bipowninv_node(expression_ptr branch) + explicit bipowinv_node(expression_ptr branch) { construct_branch_pair(branch_, branch); + assert(valid()); } inline T value() const exprtk_override { - assert(branch_.first); return (T(1) / PowOp::result(branch_.first->value())); } @@ -16420,9 +18875,14 @@ namespace exprtk return expression_node::e_ipowinv; } + inline bool valid() const exprtk_override + { + return branch_.first && branch_.first->valid(); + } + void collect_nodes(typename expression_node::noderef_list_t& node_delete_list) exprtk_override { - expression_node::ndb_t::template collect(branch_, node_delete_list); + expression_node::ndb_t::collect(branch_, node_delete_list); } std::size_t node_depth() const exprtk_override @@ -16432,8 +18892,8 @@ namespace exprtk private: - bipowninv_node(const bipowninv_node&) exprtk_delete; - bipowninv_node& operator=(const bipowninv_node&) exprtk_delete; + bipowinv_node(const bipowinv_node&) exprtk_delete; + bipowinv_node& operator=(const bipowinv_node&) exprtk_delete; branch_t branch_; }; @@ -16577,6 +19037,46 @@ namespace exprtk return false; } + template + inline bool is_loop_node(const expression_node* node) + { + if (node) + { + switch (node->type()) + { + case expression_node::e_for : + case expression_node::e_repeat : + case expression_node::e_while : return true; + default : return false; + } + } + + return false; + } + + template + inline bool is_block_node(const expression_node* node) + { + if (node) + { + if (is_loop_node(node)) + { + return true; + } + + switch (node->type()) + { + case expression_node::e_conditional : + case expression_node::e_mswitch : + case expression_node::e_switch : + case expression_node::e_vararg : return true; + default : return false; + } + } + + return false; + } + class node_allocator { public: @@ -17117,7 +19617,8 @@ namespace exprtk : param_count(pc) {} - virtual ~ifunction() {} + virtual ~ifunction() + {} #define empty_method_body(N) \ { \ @@ -17208,7 +19709,8 @@ namespace exprtk { public: - virtual ~ivararg_function() {} + virtual ~ivararg_function() + {} inline virtual T operator() (const std::vector&) { @@ -17233,12 +19735,13 @@ namespace exprtk typedef type_store generic_type; typedef typename generic_type::parameter_list parameter_list_t; - igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar) + explicit igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar) : parameter_sequence(param_seq) , rtrn_type(rtr_type) {} - virtual ~igeneric_function() {} + virtual ~igeneric_function() + {} #define igeneric_function_empty_body(N) \ { \ @@ -17262,6 +19765,8 @@ namespace exprtk inline virtual T operator() (const std::size_t&, std::string&, parameter_list_t) igeneric_function_empty_body(4) + #undef igeneric_function_empty_body + std::string parameter_sequence; return_type rtrn_type; }; @@ -17337,52 +19842,52 @@ namespace exprtk protected: - struct freefunc00 : public exprtk::ifunction + struct freefunc00 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc00(ff00_functor ff) : exprtk::ifunction(0), f(ff) {} - inline T operator() () + inline T operator() () exprtk_override { return f(); } ff00_functor f; }; - struct freefunc01 : public exprtk::ifunction + struct freefunc01 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc01(ff01_functor ff) : exprtk::ifunction(1), f(ff) {} - inline T operator() (const T& v0) + inline T operator() (const T& v0) exprtk_override { return f(v0); } ff01_functor f; }; - struct freefunc02 : public exprtk::ifunction + struct freefunc02 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc02(ff02_functor ff) : exprtk::ifunction(2), f(ff) {} - inline T operator() (const T& v0, const T& v1) + inline T operator() (const T& v0, const T& v1) exprtk_override { return f(v0, v1); } ff02_functor f; }; - struct freefunc03 : public exprtk::ifunction + struct freefunc03 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc03(ff03_functor ff) : exprtk::ifunction(3), f(ff) {} - inline T operator() (const T& v0, const T& v1, const T& v2) + inline T operator() (const T& v0, const T& v1, const T& v2) exprtk_override { return f(v0, v1, v2); } ff03_functor f; }; - struct freefunc04 : public exprtk::ifunction + struct freefunc04 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc04(ff04_functor ff) : exprtk::ifunction(4), f(ff) {} - inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3) + inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3) exprtk_override { return f(v0, v1, v2, v3); } ff04_functor f; }; @@ -17392,120 +19897,120 @@ namespace exprtk using exprtk::ifunction::operator(); explicit freefunc05(ff05_functor ff) : exprtk::ifunction(5), f(ff) {} - inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) + inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) exprtk_override { return f(v0, v1, v2, v3, v4); } ff05_functor f; }; - struct freefunc06 : public exprtk::ifunction + struct freefunc06 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc06(ff06_functor ff) : exprtk::ifunction(6), f(ff) {} - inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) + inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) exprtk_override { return f(v0, v1, v2, v3, v4, v5); } ff06_functor f; }; - struct freefunc07 : public exprtk::ifunction + struct freefunc07 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc07(ff07_functor ff) : exprtk::ifunction(7), f(ff) {} inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6) + const T& v5, const T& v6) exprtk_override { return f(v0, v1, v2, v3, v4, v5, v6); } ff07_functor f; }; - struct freefunc08 : public exprtk::ifunction + struct freefunc08 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc08(ff08_functor ff) : exprtk::ifunction(8), f(ff) {} inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7) + const T& v5, const T& v6, const T& v7) exprtk_override { return f(v0, v1, v2, v3, v4, v5, v6, v7); } ff08_functor f; }; - struct freefunc09 : public exprtk::ifunction + struct freefunc09 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc09(ff09_functor ff) : exprtk::ifunction(9), f(ff) {} inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8) + const T& v5, const T& v6, const T& v7, const T& v8) exprtk_override { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8); } ff09_functor f; }; - struct freefunc10 : public exprtk::ifunction + struct freefunc10 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc10(ff10_functor ff) : exprtk::ifunction(10), f(ff) {} inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, const T& v9) + const T& v5, const T& v6, const T& v7, const T& v8, const T& v9) exprtk_override { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); } ff10_functor f; }; - struct freefunc11 : public exprtk::ifunction + struct freefunc11 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc11(ff11_functor ff) : exprtk::ifunction(11), f(ff) {} inline T operator() (const T& v0, const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10) + const T& v5, const T& v6, const T& v7, const T& v8, const T& v9, const T& v10) exprtk_override { return f(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); } ff11_functor f; }; - struct freefunc12 : public exprtk::ifunction + struct freefunc12 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc12(ff12_functor ff) : exprtk::ifunction(12), f(ff) {} inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, - const T& v10, const T& v11) + const T& v10, const T& v11) exprtk_override { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11); } ff12_functor f; }; - struct freefunc13 : public exprtk::ifunction + struct freefunc13 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc13(ff13_functor ff) : exprtk::ifunction(13), f(ff) {} inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, - const T& v10, const T& v11, const T& v12) + const T& v10, const T& v11, const T& v12) exprtk_override { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12); } ff13_functor f; }; - struct freefunc14 : public exprtk::ifunction + struct freefunc14 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc14(ff14_functor ff) : exprtk::ifunction(14), f(ff) {} inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, - const T& v10, const T& v11, const T& v12, const T& v13) + const T& v10, const T& v11, const T& v12, const T& v13) exprtk_override { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13); } ff14_functor f; }; - struct freefunc15 : public exprtk::ifunction + struct freefunc15 exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); explicit freefunc15(ff15_functor ff) : exprtk::ifunction(15), f(ff) {} inline T operator() (const T& v00, const T& v01, const T& v02, const T& v03, const T& v04, const T& v05, const T& v06, const T& v07, const T& v08, const T& v09, - const T& v10, const T& v11, const T& v12, const T& v13, const T& v14) + const T& v10, const T& v11, const T& v12, const T& v13, const T& v14) exprtk_override { return f(v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14); } ff15_functor f; }; @@ -17765,7 +20270,7 @@ namespace exprtk { static inline bool test(const variable_node_t* p, const void* ptr) { - exprtk_debug(("ptr_match::test() - %p <--> %p\n",(void*)(&(p->ref())),ptr)); + exprtk_debug(("ptr_match::test() - %p <--> %p\n", reinterpret_cast(&(p->ref())), ptr)); return (&(p->ref()) == ptr); } }; @@ -18029,7 +20534,7 @@ namespace exprtk public: - symbol_table(const symtab_mutability_type mutability = e_mutable) + explicit symbol_table(const symtab_mutability_type mutability = e_mutable) : control_block_(control_block::create()) { control_block_->set_mutability(mutability); @@ -18508,6 +21013,34 @@ namespace exprtk return false; } + #define exprtk_define_reserved_function(NN) \ + inline bool add_reserved_function(const std::string& function_name, ff##NN##_functor function) \ + { \ + if (!valid()) \ + { return false; } \ + if (!valid_symbol(function_name,false)) \ + { return false; } \ + if (symbol_exists(function_name,false)) \ + { return false; } \ + \ + exprtk::ifunction* ifunc = new freefunc##NN(function); \ + \ + local_data().free_function_list_.push_back(ifunc); \ + \ + return add_reserved_function(function_name,(*local_data().free_function_list_.back())); \ + } \ + + exprtk_define_reserved_function(00) exprtk_define_reserved_function(01) + exprtk_define_reserved_function(02) exprtk_define_reserved_function(03) + exprtk_define_reserved_function(04) exprtk_define_reserved_function(05) + exprtk_define_reserved_function(06) exprtk_define_reserved_function(07) + exprtk_define_reserved_function(08) exprtk_define_reserved_function(09) + exprtk_define_reserved_function(10) exprtk_define_reserved_function(11) + exprtk_define_reserved_function(12) exprtk_define_reserved_function(13) + exprtk_define_reserved_function(14) exprtk_define_reserved_function(15) + + #undef exprtk_define_reserved_function + template inline bool add_vector(const std::string& vector_name, T (&v)[N]) { @@ -18682,12 +21215,48 @@ namespace exprtk template class Sequence> - inline std::size_t get_vector_list(Sequence& vlist) const + inline std::size_t get_vector_list(Sequence& vec_list) const { if (!valid()) return 0; else - return local_data().vector_store.get_list(vlist); + return local_data().vector_store.get_list(vec_list); + } + + template class Sequence> + inline std::size_t get_function_list(Sequence& function_list) const + { + if (!valid()) + return 0; + + std::vector function_names; + std::size_t count = 0; + + count += local_data().function_store .get_list(function_names); + count += local_data().vararg_function_store .get_list(function_names); + count += local_data().generic_function_store .get_list(function_names); + count += local_data().string_function_store .get_list(function_names); + count += local_data().overload_function_store.get_list(function_names); + + std::set function_set; + + for (std::size_t i = 0; i < function_names.size(); ++i) + { + function_set.insert(function_names[i]); + } + + std::copy(function_set.begin(), function_set.end(), + std::back_inserter(function_list)); + + return count; + } + + inline std::vector get_function_list() const + { + std::vector result; + get_function_list(result); + return result; } inline bool symbol_exists(const std::string& symbol_name, const bool check_reserved_symb = true) const @@ -18878,6 +21447,38 @@ namespace exprtk } } + inline void load_variables_from(const symbol_table& st) + { + std::vector name_list; + + st.local_data().variable_store.get_list(name_list); + + if (!name_list.empty()) + { + for (std::size_t i = 0; i < name_list.size(); ++i) + { + T& variable = st.get_variable(name_list[i])->ref(); + add_variable(name_list[i], variable); + } + } + } + + inline void load_vectors_from(const symbol_table& st) + { + std::vector name_list; + + st.local_data().vector_store.get_list(name_list); + + if (!name_list.empty()) + { + for (std::size_t i = 0; i < name_list.size(); ++i) + { + vector_holder_t& vecholder = *st.get_vector(name_list[i]); + add_vector(name_list[i], vecholder.data(), vecholder.size()); + } + } + } + private: inline bool valid_symbol(const std::string& symbol, const bool check_reserved_symb = true) const @@ -18973,6 +21574,21 @@ namespace exprtk e_string }; + static std::string to_str(data_type dt) + { + switch(dt) + { + case e_unknown : return "e_unknown "; + case e_expr : return "e_expr" ; + case e_vecholder : return "e_vecholder"; + case e_data : return "e_data" ; + case e_vecdata : return "e_vecdata" ; + case e_string : return "e_string" ; + } + + return ""; + } + struct data_pack { data_pack() @@ -19178,17 +21794,18 @@ namespace exprtk return details::is_true(value()); } - inline void register_symbol_table(symbol_table& st) + inline bool register_symbol_table(symbol_table& st) { for (std::size_t i = 0; i < symbol_table_list_.size(); ++i) { - if (&st == &symbol_table_list_[i]) + if (st == symbol_table_list_[i]) { - return; + return false; } } symbol_table_list_.push_back(st); + return true; } inline const symbol_table& get_symbol_table(const std::size_t& index = 0) const @@ -19201,6 +21818,11 @@ namespace exprtk return symbol_table_list_[index]; } + std::size_t num_symbol_tables() const + { + return symbol_table_list_.size(); + } + typedef results_context results_context_t; inline const results_context_t& results() const @@ -19330,6 +21952,8 @@ namespace exprtk friend class parser; friend class expression_helper; friend class function_compositor; + template + friend bool is_valid(const expression& expr); }; // class expression template @@ -19337,55 +21961,165 @@ namespace exprtk { public: - static inline bool is_constant(const expression& expr) + enum node_types + { + e_literal, + e_variable, + e_string, + e_unary, + e_binary, + e_function, + e_vararg, + e_null, + e_assert, + e_sf3ext, + e_sf4ext + }; + + static inline bool is_literal(const expression& expr) { - return details::is_constant_node(expr.control_block_->expr); + return expr.control_block_ && details::is_literal_node(expr.control_block_->expr); } static inline bool is_variable(const expression& expr) { - return details::is_variable_node(expr.control_block_->expr); + return expr.control_block_ && details::is_variable_node(expr.control_block_->expr); + } + + static inline bool is_string(const expression& expr) + { + return expr.control_block_ && details::is_generally_string_node(expr.control_block_->expr); } static inline bool is_unary(const expression& expr) { - return details::is_unary_node(expr.control_block_->expr); + return expr.control_block_ && details::is_unary_node(expr.control_block_->expr); } static inline bool is_binary(const expression& expr) { - return details::is_binary_node(expr.control_block_->expr); + return expr.control_block_ && details::is_binary_node(expr.control_block_->expr); } static inline bool is_function(const expression& expr) { - return details::is_function(expr.control_block_->expr); + return expr.control_block_ && details::is_function(expr.control_block_->expr); + } + + static inline bool is_vararg(const expression& expr) + { + return expr.control_block_ && details::is_vararg_node(expr.control_block_->expr); } static inline bool is_null(const expression& expr) { - return details::is_null_node(expr.control_block_->expr); + return expr.control_block_ && details::is_null_node(expr.control_block_->expr); + } + + static inline bool is_assert(const expression& expr) + { + return expr.control_block_ && details::is_assert_node(expr.control_block_->expr); + } + + static inline bool is_sf3ext(const expression& expr) + { + return expr.control_block_ && details::is_sf3ext_node(expr.control_block_->expr); + } + + static inline bool is_sf4ext(const expression& expr) + { + return expr.control_block_ && details::is_sf4ext_node(expr.control_block_->expr); + } + + static inline bool is_type(const expression& expr, const node_types node_type) + { + if (0 == expr.control_block_) + { + return false; + } + + switch (node_type) + { + case e_literal : return is_literal_node(expr); + case e_variable : return is_variable (expr); + case e_string : return is_string (expr); + case e_unary : return is_unary (expr); + case e_binary : return is_binary (expr); + case e_function : return is_function (expr); + case e_null : return is_null (expr); + case e_assert : return is_assert (expr); + case e_sf3ext : return is_sf3ext (expr); + case e_sf4ext : return is_sf4ext (expr); + }; + + return false; + } + + static inline bool match_type_sequence(const expression& expr, const std::vector& type_seq) + { + if ((0 == expr.control_block_) || !is_vararg(expr)) + { + return false; + } + + typedef details::vararg_node > mo_vararg_t; + + mo_vararg_t* vnode = dynamic_cast(expr.control_block_->expr); + + if ( + (0 == vnode) || + type_seq.empty() || + (vnode->size() < type_seq.size()) + ) + { + return false; + } + + for (std::size_t i = 0; i < type_seq.size(); ++i) + { + assert((*vnode)[i]); + + switch(type_seq[i]) + { + case e_literal : { if (details::is_literal_node ((*vnode)[i])) continue; } break; + case e_variable : { if (details::is_variable_node ((*vnode)[i])) continue; } break; + case e_string : { if (details::is_generally_string_node((*vnode)[i])) continue; } break; + case e_unary : { if (details::is_unary_node ((*vnode)[i])) continue; } break; + case e_binary : { if (details::is_binary_node ((*vnode)[i])) continue; } break; + case e_function : { if (details::is_function ((*vnode)[i])) continue; } break; + case e_null : { if (details::is_null_node ((*vnode)[i])) continue; } break; + case e_assert : { if (details::is_assert_node ((*vnode)[i])) continue; } break; + case e_sf3ext : { if (details::is_sf3ext_node ((*vnode)[i])) continue; } break; + case e_sf4ext : { if (details::is_sf4ext_node ((*vnode)[i])) continue; } break; + case e_vararg : break; + } + + return false; + } + + return true; } }; template inline bool is_valid(const expression& expr) { - return !expression_helper::is_null(expr); + return expr.control_block_ && !expression_helper::is_null(expr); } namespace parser_error { enum error_mode { - e_unknown = 0, - e_syntax = 1, - e_token = 2, - e_numeric = 4, - e_symtab = 5, - e_lexer = 6, - e_helper = 7, - e_parser = 8 + e_unknown = 0, + e_syntax = 1, + e_token = 2, + e_numeric = 4, + e_symtab = 5, + e_lexer = 6, + e_synthesis = 7, + e_helper = 8, + e_parser = 9 }; struct type @@ -19414,7 +22148,7 @@ namespace exprtk t.token.type = lexer::token::e_error; t.diagnostic = diagnostic; t.src_location = src_location; - exprtk_debug(("%s\n",diagnostic .c_str())); + exprtk_debug(("%s\n", diagnostic .c_str())); return t; } @@ -19428,7 +22162,7 @@ namespace exprtk t.token = tk; t.diagnostic = diagnostic; t.src_location = src_location; - exprtk_debug(("%s\n",diagnostic .c_str())); + exprtk_debug(("%s\n", diagnostic .c_str())); return t; } @@ -19520,70 +22254,79 @@ namespace exprtk e_level10, e_level11, e_level12, e_level13, e_level14 }; - typedef const T& cref_t; - typedef const T const_t; - typedef ifunction F; - typedef ivararg_function VAF; - typedef igeneric_function GF; - typedef ifunction ifunction_t; - typedef ivararg_function ivararg_function_t; - typedef igeneric_function igeneric_function_t; - typedef details::expression_node expression_node_t; - typedef details::literal_node literal_node_t; - typedef details::unary_node unary_node_t; - typedef details::binary_node binary_node_t; - typedef details::trinary_node trinary_node_t; - typedef details::quaternary_node quaternary_node_t; - typedef details::conditional_node conditional_node_t; - typedef details::cons_conditional_node cons_conditional_node_t; - typedef details::while_loop_node while_loop_node_t; - typedef details::repeat_until_loop_node repeat_until_loop_node_t; - typedef details::for_loop_node for_loop_node_t; - typedef details::while_loop_rtc_node while_loop_rtc_node_t; - typedef details::repeat_until_loop_rtc_node repeat_until_loop_rtc_node_t; - typedef details::for_loop_rtc_node for_loop_rtc_node_t; + typedef const T& cref_t; + typedef const T const_t; + typedef ifunction F; + typedef ivararg_function VAF; + typedef igeneric_function GF; + typedef ifunction ifunction_t; + typedef ivararg_function ivararg_function_t; + typedef igeneric_function igeneric_function_t; + typedef details::expression_node expression_node_t; + typedef details::literal_node literal_node_t; + typedef details::unary_node unary_node_t; + typedef details::binary_node binary_node_t; + typedef details::trinary_node trinary_node_t; + typedef details::quaternary_node quaternary_node_t; + typedef details::conditional_node conditional_node_t; + typedef details::cons_conditional_node cons_conditional_node_t; + typedef details::while_loop_node while_loop_node_t; + typedef details::repeat_until_loop_node repeat_until_loop_node_t; + typedef details::for_loop_node for_loop_node_t; + typedef details::while_loop_rtc_node while_loop_rtc_node_t; + typedef details::repeat_until_loop_rtc_node repeat_until_loop_rtc_node_t; + typedef details::for_loop_rtc_node for_loop_rtc_node_t; #ifndef exprtk_disable_break_continue - typedef details::while_loop_bc_node while_loop_bc_node_t; - typedef details::repeat_until_loop_bc_node repeat_until_loop_bc_node_t; - typedef details::for_loop_bc_node for_loop_bc_node_t; - typedef details::while_loop_bc_rtc_node while_loop_bc_rtc_node_t; - typedef details::repeat_until_loop_bc_rtc_node repeat_until_loop_bc_rtc_node_t; - typedef details::for_loop_bc_rtc_node for_loop_bc_rtc_node_t; + typedef details::while_loop_bc_node while_loop_bc_node_t; + typedef details::repeat_until_loop_bc_node repeat_until_loop_bc_node_t; + typedef details::for_loop_bc_node for_loop_bc_node_t; + typedef details::while_loop_bc_rtc_node while_loop_bc_rtc_node_t; + typedef details::repeat_until_loop_bc_rtc_node repeat_until_loop_bc_rtc_node_t; + typedef details::for_loop_bc_rtc_node for_loop_bc_rtc_node_t; #endif - typedef details::switch_node switch_node_t; - typedef details::variable_node variable_node_t; - typedef details::vector_elem_node vector_elem_node_t; - typedef details::rebasevector_elem_node rebasevector_elem_node_t; - typedef details::rebasevector_celem_node rebasevector_celem_node_t; - typedef details::vector_node vector_node_t; - typedef details::range_pack range_t; + typedef details::switch_node switch_node_t; + typedef details::variable_node variable_node_t; + typedef details::vector_elem_node vector_elem_node_t; + typedef details::vector_celem_node vector_celem_node_t; + typedef details::vector_elem_rtc_node vector_elem_rtc_node_t; + typedef details::vector_celem_rtc_node vector_celem_rtc_node_t; + typedef details::rebasevector_elem_node rebasevector_elem_node_t; + typedef details::rebasevector_celem_node rebasevector_celem_node_t; + typedef details::rebasevector_elem_rtc_node rebasevector_elem_rtc_node_t; + typedef details::rebasevector_celem_rtc_node rebasevector_celem_rtc_node_t; + typedef details::vector_node vector_node_t; + typedef details::vector_size_node vector_size_node_t; + typedef details::range_pack range_t; #ifndef exprtk_disable_string_capabilities - typedef details::stringvar_node stringvar_node_t; - typedef details::string_literal_node string_literal_node_t; - typedef details::string_range_node string_range_node_t; - typedef details::const_string_range_node const_string_range_node_t; - typedef details::generic_string_range_node generic_string_range_node_t; - typedef details::string_concat_node string_concat_node_t; - typedef details::assignment_string_node assignment_string_node_t; - typedef details::assignment_string_range_node assignment_string_range_node_t; - typedef details::conditional_string_node conditional_string_node_t; - typedef details::cons_conditional_str_node cons_conditional_str_node_t; + typedef details::stringvar_node stringvar_node_t; + typedef details::string_literal_node string_literal_node_t; + typedef details::string_range_node string_range_node_t; + typedef details::const_string_range_node const_string_range_node_t; + typedef details::generic_string_range_node generic_string_range_node_t; + typedef details::string_concat_node string_concat_node_t; + typedef details::assignment_string_node assignment_string_node_t; + typedef details::assignment_string_range_node assignment_string_range_node_t; + typedef details::conditional_string_node conditional_string_node_t; + typedef details::cons_conditional_str_node cons_conditional_str_node_t; #endif - typedef details::assignment_node assignment_node_t; - typedef details::assignment_vec_elem_node assignment_vec_elem_node_t; - typedef details::assignment_rebasevec_elem_node assignment_rebasevec_elem_node_t; - typedef details::assignment_rebasevec_celem_node assignment_rebasevec_celem_node_t; - typedef details::assignment_vec_node assignment_vec_node_t; - typedef details::assignment_vecvec_node assignment_vecvec_node_t; - typedef details::conditional_vector_node conditional_vector_node_t; - typedef details::scand_node scand_node_t; - typedef details::scor_node scor_node_t; - typedef lexer::token token_t; - typedef expression_node_t* expression_node_ptr; - typedef expression expression_t; - typedef symbol_table symbol_table_t; - typedef typename expression::symtab_list_t symbol_table_list_t; - typedef details::vector_holder* vector_holder_ptr; + typedef details::assignment_node assignment_node_t; + typedef details::assignment_vec_elem_node assignment_vec_elem_node_t; + typedef details::assignment_vec_elem_rtc_node assignment_vec_elem_rtc_node_t; + typedef details::assignment_rebasevec_elem_node assignment_rebasevec_elem_node_t; + typedef details::assignment_rebasevec_elem_rtc_node assignment_rebasevec_elem_rtc_node_t; + typedef details::assignment_rebasevec_celem_node assignment_rebasevec_celem_node_t; + typedef details::assignment_vec_node assignment_vec_node_t; + typedef details::assignment_vecvec_node assignment_vecvec_node_t; + typedef details::conditional_vector_node conditional_vector_node_t; + typedef details::scand_node scand_node_t; + typedef details::scor_node scor_node_t; + typedef lexer::token token_t; + typedef expression_node_t* expression_node_ptr; + typedef expression expression_t; + typedef symbol_table symbol_table_t; + typedef typename expression::symtab_list_t symbol_table_list_t; + typedef details::vector_holder vector_holder_t; + typedef vector_holder_t* vector_holder_ptr; typedef typename details::functor_t functor_t; typedef typename functor_t::qfunc_t quaternary_functor_t; @@ -19636,6 +22379,7 @@ namespace exprtk enum element_type { e_none , + e_literal , e_variable, e_vector , e_vecelem , @@ -19643,6 +22387,7 @@ namespace exprtk }; typedef details::vector_holder vector_holder_t; + typedef literal_node_t* literal_node_ptr; typedef variable_node_t* variable_node_ptr; typedef vector_holder_t* vector_holder_ptr; typedef expression_node_t* expression_node_ptr; @@ -19657,8 +22402,8 @@ namespace exprtk , depth(std::numeric_limits::max()) , ref_count(0) , ip_index (0) - , type (e_none) - , active(false) + , type (e_none) + , active (false) , data (0) , var_node (0) , vec_node (0) @@ -19842,6 +22587,10 @@ namespace exprtk switch (se.type) { + case scope_element::e_literal : delete reinterpret_cast(se.data); + delete se.var_node; + break; + case scope_element::e_variable : delete reinterpret_cast(se.data); delete se.var_node; break; @@ -19906,6 +22655,25 @@ namespace exprtk return expression_node_ptr(0); } + inline std::string get_vector_name(const T* data) + { + for (std::size_t i = 0; i < element_.size(); ++i) + { + scope_element& se = element_[i]; + + if ( + se.active && + se.vec_node && + (se.vec_node->data() == data) + ) + { + return se.name; + } + } + + return "neo-vector"; + } + private: scope_element_manager(const scope_element_manager&) exprtk_delete; @@ -20092,16 +22860,17 @@ namespace exprtk if (++parser_.state_.stack_depth > parser_.settings_.max_stack_depth_) { limit_exceeded_ = true; - parser_.set_error( - make_error(parser_error::e_parser, - "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) + - " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_), - exprtk_error_location)); + parser_.set_error(make_error( + parser_error::e_parser, + "ERR000 - Current stack depth " + details::to_str(parser_.state_.stack_depth) + + " exceeds maximum allowed stack depth of " + details::to_str(parser_.settings_.max_stack_depth_), + exprtk_error_location)); } } ~stack_limit_handler() { + assert(parser_.state_.stack_depth > 0); parser_.state_.stack_depth--; } @@ -20211,22 +22980,23 @@ namespace exprtk inline variable_context get_variable_context(const std::string& variable_name) const { variable_context result; - if (!valid_symbol(variable_name)) - return result; - for (std::size_t i = 0; i < symtab_list_.size(); ++i) + if (valid_symbol(variable_name)) { - if (!symtab_list_[i].valid()) + for (std::size_t i = 0; i < symtab_list_.size(); ++i) { - continue; - } + if (!symtab_list_[i].valid()) + { + continue; + } - result.variable = local_data(i) - .variable_store.get(variable_name); - if (result.variable) - { - result.symbol_table = &symtab_list_[i]; - break; + result.variable = local_data(i) + .variable_store.get(variable_name); + if (result.variable) + { + result.symbol_table = &symtab_list_[i]; + break; + } } } @@ -20461,12 +23231,16 @@ namespace exprtk for (std::size_t i = 0; i < symtab_list_.size(); ++i) { if (!symtab_list_[i].valid()) + { continue; - else - result = - local_data(i).vector_store.get(vector_name); + } - if (result) break; + result = local_data(i).vector_store.get(vector_name); + + if (result) + { + break; + } } return result; @@ -20480,9 +23254,14 @@ namespace exprtk for (std::size_t i = 0; i < symtab_list_.size(); ++i) { if (!symtab_list_[i].valid()) + { continue; - else if (local_data(i).variable_store.is_constant(symbol_name)) + } + + if (local_data(i).variable_store.is_constant(symbol_name)) + { return true; + } } return false; @@ -20513,9 +23292,14 @@ namespace exprtk for (std::size_t i = 0; i < symtab_list_.size(); ++i) { if (!symtab_list_[i].valid()) + { continue; - else if (symtab_list_[i].symbol_exists(symbol)) + } + + if (symtab_list_[i].symbol_exists(symbol)) + { return true; + } } return false; @@ -20675,6 +23459,7 @@ namespace exprtk { parsing_return_stmt = false; parsing_break_stmt = false; + parsing_assert_stmt = false; return_stmt_present = false; side_effect_present = false; scope_depth = 0; @@ -20692,12 +23477,13 @@ namespace exprtk { side_effect_present = true; - exprtk_debug(("activate_side_effect() - caller: %s\n",source.c_str())); + exprtk_debug(("activate_side_effect() - caller: %s\n", source.c_str())); } } bool parsing_return_stmt; bool parsing_break_stmt; + bool parsing_assert_stmt; bool return_stmt_present; bool side_effect_present; bool type_check_enabled; @@ -20730,7 +23516,8 @@ namespace exprtk : mode(m) {} - virtual ~unknown_symbol_resolver() {} + virtual ~unknown_symbol_resolver() + {} virtual bool process(const std::string& /*unknown_symbol*/, usr_symbol_type& st, @@ -20806,11 +23593,14 @@ namespace exprtk details::case_normalise(symbol_name_list_[i].first); } - std::sort(symbol_name_list_.begin(),symbol_name_list_.end()); + std::sort(symbol_name_list_.begin(), symbol_name_list_.end()); - std::unique_copy(symbol_name_list_.begin(), - symbol_name_list_.end (), - std::back_inserter(symbols_list)); + std::unique_copy + ( + symbol_name_list_.begin(), + symbol_name_list_.end (), + std::back_inserter(symbols_list) + ); return symbols_list.size(); } @@ -20831,9 +23621,12 @@ namespace exprtk std::sort(assignment_name_list_.begin(),assignment_name_list_.end()); - std::unique_copy(assignment_name_list_.begin(), - assignment_name_list_.end (), - std::back_inserter(assignment_list)); + std::unique_copy + ( + assignment_name_list_.begin(), + assignment_name_list_.end (), + std::back_inserter(assignment_list) + ); return assignment_list.size(); } @@ -21020,7 +23813,7 @@ namespace exprtk e_ineq_gte , e_ineq_gt }; - static const std::size_t compile_all_opts = + static const std::size_t default_compile_all_opts = e_replacer + e_joiner + e_numeric_check + @@ -21029,9 +23822,10 @@ namespace exprtk e_commutative_check + e_strength_reduction; - settings_store(const std::size_t compile_options = compile_all_opts) + settings_store(const std::size_t compile_options = default_compile_all_opts) : max_stack_depth_(400) , max_node_depth_(10000) + , max_local_vector_size_(2000000000) { load_compile_options(compile_options); } @@ -21078,12 +23872,24 @@ namespace exprtk return (*this); } + settings_store& enable_commutative_check() + { + enable_commutative_check_ = true; + return (*this); + } + + settings_store& enable_strength_reduction() + { + enable_strength_reduction_ = true; + return (*this); + } + settings_store& disable_all_base_functions() { std::copy(details::base_function_list, details::base_function_list + details::base_function_list_size, std::insert_iterator - (disabled_func_set_, disabled_func_set_.begin())); + (disabled_func_set_, disabled_func_set_.begin())); return (*this); } @@ -21092,7 +23898,7 @@ namespace exprtk std::copy(details::cntrl_struct_list, details::cntrl_struct_list + details::cntrl_struct_list_size, std::insert_iterator - (disabled_ctrl_set_, disabled_ctrl_set_.begin())); + (disabled_ctrl_set_, disabled_ctrl_set_.begin())); return (*this); } @@ -21110,7 +23916,7 @@ namespace exprtk std::copy(details::arithmetic_ops_list, details::arithmetic_ops_list + details::arithmetic_ops_list_size, std::insert_iterator - (disabled_arithmetic_set_, disabled_arithmetic_set_.begin())); + (disabled_arithmetic_set_, disabled_arithmetic_set_.begin())); return (*this); } @@ -21119,7 +23925,7 @@ namespace exprtk std::copy(details::assignment_ops_list, details::assignment_ops_list + details::assignment_ops_list_size, std::insert_iterator - (disabled_assignment_set_, disabled_assignment_set_.begin())); + (disabled_assignment_set_, disabled_assignment_set_.begin())); return (*this); } @@ -21128,7 +23934,7 @@ namespace exprtk std::copy(details::inequality_ops_list, details::inequality_ops_list + details::inequality_ops_list_size, std::insert_iterator - (disabled_inequality_set_, disabled_inequality_set_.begin())); + (disabled_inequality_set_, disabled_inequality_set_.begin())); return (*this); } @@ -21138,6 +23944,18 @@ namespace exprtk return (*this); } + settings_store& disable_commutative_check() + { + enable_commutative_check_ = false; + return (*this); + } + + settings_store& disable_strength_reduction() + { + enable_strength_reduction_ = false; + return (*this); + } + bool replacer_enabled () const { return enable_replacer_; } bool commutative_check_enabled () const { return enable_commutative_check_; } bool joiner_enabled () const { return enable_joiner_; } @@ -21263,7 +24081,7 @@ namespace exprtk .find(inequality_opr_to_string(inequality)); } - settings_store& disable_base_function(settings_base_funcs bf) + settings_store& disable_base_function(const settings_base_funcs bf) { if ( (e_bf_unknown != bf) && @@ -21276,7 +24094,7 @@ namespace exprtk return (*this); } - settings_store& disable_control_structure(settings_control_structs ctrl_struct) + settings_store& disable_control_structure(const settings_control_structs ctrl_struct) { if ( (e_ctrl_unknown != ctrl_struct) && @@ -21289,7 +24107,7 @@ namespace exprtk return (*this); } - settings_store& disable_logic_operation(settings_logic_opr logic) + settings_store& disable_logic_operation(const settings_logic_opr logic) { if ( (e_logic_unknown != logic) && @@ -21302,7 +24120,7 @@ namespace exprtk return (*this); } - settings_store& disable_arithmetic_operation(settings_arithmetic_opr arithmetic) + settings_store& disable_arithmetic_operation(const settings_arithmetic_opr arithmetic) { if ( (e_arith_unknown != arithmetic) && @@ -21315,7 +24133,7 @@ namespace exprtk return (*this); } - settings_store& disable_assignment_operation(settings_assignment_opr assignment) + settings_store& disable_assignment_operation(const settings_assignment_opr assignment) { if ( (e_assign_unknown != assignment) && @@ -21328,7 +24146,7 @@ namespace exprtk return (*this); } - settings_store& disable_inequality_operation(settings_inequality_opr inequality) + settings_store& disable_inequality_operation(const settings_inequality_opr inequality) { if ( (e_ineq_unknown != inequality) && @@ -21341,7 +24159,7 @@ namespace exprtk return (*this); } - settings_store& enable_base_function(settings_base_funcs bf) + settings_store& enable_base_function(const settings_base_funcs bf) { if ( (e_bf_unknown != bf) && @@ -21359,7 +24177,7 @@ namespace exprtk return (*this); } - settings_store& enable_control_structure(settings_control_structs ctrl_struct) + settings_store& enable_control_structure(const settings_control_structs ctrl_struct) { if ( (e_ctrl_unknown != ctrl_struct) && @@ -21377,7 +24195,7 @@ namespace exprtk return (*this); } - settings_store& enable_logic_operation(settings_logic_opr logic) + settings_store& enable_logic_operation(const settings_logic_opr logic) { if ( (e_logic_unknown != logic) && @@ -21395,7 +24213,7 @@ namespace exprtk return (*this); } - settings_store& enable_arithmetic_operation(settings_arithmetic_opr arithmetic) + settings_store& enable_arithmetic_operation(const settings_arithmetic_opr arithmetic) { if ( (e_arith_unknown != arithmetic) && @@ -21413,7 +24231,7 @@ namespace exprtk return (*this); } - settings_store& enable_assignment_operation(settings_assignment_opr assignment) + settings_store& enable_assignment_operation(const settings_assignment_opr assignment) { if ( (e_assign_unknown != assignment) && @@ -21431,7 +24249,7 @@ namespace exprtk return (*this); } - settings_store& enable_inequality_operation(settings_inequality_opr inequality) + settings_store& enable_inequality_operation(const settings_inequality_opr inequality) { if ( (e_ineq_unknown != inequality) && @@ -21459,6 +24277,26 @@ namespace exprtk max_node_depth_ = max_node_depth; } + void set_max_local_vector_size(const std::size_t max_local_vector_size) + { + max_local_vector_size_ = max_local_vector_size; + } + + std::size_t max_stack_depth() const + { + return max_stack_depth_; + } + + std::size_t max_node_depth() const + { + return max_node_depth_; + } + + std::size_t max_local_vector_size() const + { + return max_local_vector_size_; + } + private: void load_compile_options(const std::size_t compile_options) @@ -21501,6 +24339,7 @@ namespace exprtk case details::e_mul : return "*"; case details::e_div : return "/"; case details::e_mod : return "%"; + case details::e_pow : return "^"; default : return "" ; } } @@ -21559,13 +24398,14 @@ namespace exprtk std::size_t max_stack_depth_; std::size_t max_node_depth_; + std::size_t max_local_vector_size_; friend class parser; }; typedef settings_store settings_t; - parser(const settings_t& settings = settings_t()) + explicit parser(const settings_t& settings = settings_t()) : settings_(settings) , resolve_unknown_symbol_(false) , results_context_(0) @@ -21581,6 +24421,9 @@ namespace exprtk , operator_joiner_2_(2) , operator_joiner_3_(3) , loop_runtime_check_(0) + , vector_access_runtime_check_(0) + , compilation_check_ptr_(0) + , assert_check_(0) { init_precompilation(); @@ -21593,15 +24436,16 @@ namespace exprtk expression_generator_.init_synthesize_map(); expression_generator_.set_parser(*this); - expression_generator_.set_uom(unary_op_map_); - expression_generator_.set_bom(binary_op_map_); + expression_generator_.set_uom (unary_op_map_ ); + expression_generator_.set_bom (binary_op_map_ ); expression_generator_.set_ibom(inv_binary_op_map_); - expression_generator_.set_sf3m(sf3_map_); - expression_generator_.set_sf4m(sf4_map_); + expression_generator_.set_sf3m(sf3_map_ ); + expression_generator_.set_sf4m(sf4_map_ ); expression_generator_.set_strength_reduction_state(settings_.strength_reduction_enabled()); } - ~parser() {} + ~parser() + {} inline void init_precompilation() { @@ -21669,11 +24513,15 @@ namespace exprtk inline bool compile(const std::string& expression_string, expression& expr) { - state_ .reset(); - error_list_ .clear(); - brkcnt_list_ .clear(); - synthesis_error_.clear(); - sem_ .cleanup(); + state_ .reset(); + error_list_ .clear(); + brkcnt_list_ .clear(); + synthesis_error_ .clear(); + immutable_memory_map_.reset(); + immutable_symtok_map_.clear(); + current_state_stack_ .clear(); + assert_ids_ .clear(); + sem_ .cleanup(); return_cleanup(); @@ -21681,10 +24529,10 @@ namespace exprtk if (expression_string.empty()) { - set_error( - make_error(parser_error::e_syntax, - "ERR001 - Empty expression!", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + "ERR001 - Empty expression!", + exprtk_error_location)); return false; } @@ -21697,19 +24545,31 @@ namespace exprtk if (lexer().empty()) { - set_error( - make_error(parser_error::e_syntax, - "ERR002 - Empty expression!", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + "ERR002 - Empty expression!", + exprtk_error_location)); return false; } + if (halt_compilation_check()) + { + exprtk_debug(("halt_compilation_check() - compile checkpoint 0\n")); + return false; + } + if (!run_assemblies()) { return false; } + if (halt_compilation_check()) + { + exprtk_debug(("halt_compilation_check() - compile checkpoint 1\n")); + return false; + } + symtab_store_.symtab_list_ = expr.get_symbol_table_list(); dec_.clear(); @@ -21743,11 +24603,11 @@ namespace exprtk { if (error_list_.empty()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR003 - Invalid expression encountered", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR003 - Invalid expression encountered", + exprtk_error_location)); } if ((0 != e) && branch_deletable(e)) @@ -21799,11 +24659,11 @@ namespace exprtk default : diagnostic += "Unknown compiler error"; } - set_error( - make_error(parser_error::e_lexer, - lexer()[i], - diagnostic + ": " + lexer()[i].value, - exprtk_error_location)); + set_error(make_error( + parser_error::e_lexer, + lexer()[i], + diagnostic + ": " + lexer()[i].value, + exprtk_error_location)); } } } @@ -21842,11 +24702,11 @@ namespace exprtk if (0 != (bracket_checker_ptr = dynamic_cast(helper_assembly_.error_token_scanner))) { - set_error( - make_error(parser_error::e_token, - bracket_checker_ptr->error_token(), - "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_token, + bracket_checker_ptr->error_token(), + "ERR005 - Mismatched brackets: '" + bracket_checker_ptr->error_token().value + "'", + exprtk_error_location)); } else if (0 != (numeric_checker_ptr = dynamic_cast*>(helper_assembly_.error_token_scanner))) { @@ -21854,11 +24714,11 @@ namespace exprtk { lexer::token error_token = lexer()[numeric_checker_ptr->error_index(i)]; - set_error( - make_error(parser_error::e_token, - error_token, - "ERR006 - Invalid numeric token: '" + error_token.value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_token, + error_token, + "ERR006 - Invalid numeric token: '" + error_token.value + "'", + exprtk_error_location)); } if (numeric_checker_ptr->error_count()) @@ -21872,13 +24732,13 @@ namespace exprtk { std::pair error_token = sequence_validator_ptr->error(i); - set_error( - make_error(parser_error::e_token, - error_token.first, - "ERR007 - Invalid token sequence: '" + - error_token.first.value + "' and '" + - error_token.second.value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_token, + error_token.first, + "ERR007 - Invalid token sequence: '" + + error_token.first.value + "' and '" + + error_token.second.value + "'", + exprtk_error_location)); } if (sequence_validator_ptr->error_count()) @@ -21892,13 +24752,13 @@ namespace exprtk { std::pair error_token = sequence_validator3_ptr->error(i); - set_error( - make_error(parser_error::e_token, - error_token.first, - "ERR008 - Invalid token sequence: '" + - error_token.first.value + "' and '" + - error_token.second.value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_token, + error_token.first, + "ERR008 - Invalid token sequence: '" + + error_token.first.value + "' and '" + + error_token.second.value + "'", + exprtk_error_location)); } if (sequence_validator3_ptr->error_count()) @@ -21923,9 +24783,11 @@ namespace exprtk inline parser_error::type get_error(const std::size_t& index) const { if (index < error_list_.size()) + { return error_list_[index]; - else - throw std::invalid_argument("parser::get_error() - Invalid error index specificed"); + } + + throw std::invalid_argument("parser::get_error() - Invalid error index specified"); } inline std::string error() const @@ -21994,11 +24856,41 @@ namespace exprtk loop_runtime_check_ = &lrtchk; } + inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk) + { + vector_access_runtime_check_ = &vartchk; + } + + inline void register_compilation_timeout_check(compilation_check& compchk) + { + compilation_check_ptr_ = &compchk; + } + + inline void register_assert_check(assert_check& assrt_chck) + { + assert_check_ = &assrt_chck; + } + inline void clear_loop_runtime_check() { loop_runtime_check_ = loop_runtime_check_ptr(0); } + inline void clear_vector_access_runtime_check() + { + vector_access_runtime_check_ = vector_access_runtime_check_ptr(0); + } + + inline void clear_compilation_timeout_check() + { + compilation_check_ptr_ = compilation_check_ptr(0); + } + + inline void clear_assert_check() + { + assert_check_ = assert_check_ptr(0); + } + private: inline bool valid_base_operation(const std::string& symbol) const @@ -22102,11 +24994,11 @@ namespace exprtk { if (error_list_.empty()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR009 - Invalid expression encountered", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR009 - Invalid expression encountered", + exprtk_error_location)); } return error_node(); @@ -22132,15 +25024,31 @@ namespace exprtk exprtk_debug(("-------------------------------------------------\n")); } - if (lexer().finished()) - break; - else if (token_is(token_t::e_eof,prsrhlpr_t::e_hold)) + if (token_is(token_t::e_eof,prsrhlpr_t::e_hold)) { if (lexer().finished()) break; else next_token(); } + else if ( + !settings_.commutative_check_enabled() && + ( + current_token().type == token_t::e_symbol || + current_token().type == token_t::e_number || + current_token().type == token_t::e_string || + token_is_bracket(prsrhlpr_t::e_hold) + ) + ) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR010 - Invalid syntax '" + current_token().value + "' possible missing operator or context", + exprtk_error_location)); + + return error_node(); + } } if ( @@ -22158,13 +25066,17 @@ namespace exprtk return result; } - std::string construct_subexpr(lexer::token& begin_token, lexer::token& end_token) + std::string construct_subexpr(lexer::token& begin_token, + lexer::token& end_token, + const bool cleanup_whitespace = true) { std::string result = lexer().substr(begin_token.position,end_token.position); - - for (std::size_t i = 0; i < result.size(); ++i) + if (cleanup_whitespace) { - if (details::is_whitespace(result[i])) result[i] = ' '; + for (std::size_t i = 0; i < result.size(); ++i) + { + if (details::is_whitespace(result[i])) result[i] = ' '; + } } return result; @@ -22176,11 +25088,13 @@ namespace exprtk { inline void set(const precedence_level& l, const precedence_level& r, - const details::operator_type& o) + const details::operator_type& o, + const token_t tkn = token_t()) { - left = l; - right = r; + left = l; + right = r; operation = o; + token = tkn; } inline void reset() @@ -22193,10 +25107,58 @@ namespace exprtk precedence_level left; precedence_level right; details::operator_type operation; + token_t token; }; + inline void push_current_state(const state_t current_state) + { + current_state_stack_.push_back(current_state); + } + + inline void pop_current_state() + { + if (!current_state_stack_.empty()) + { + current_state_stack_.pop_back(); + } + } + + inline state_t current_state() const + { + return (!current_state_stack_.empty()) ? + current_state_stack_.back() : + state_t(); + } + + inline bool halt_compilation_check() + { + compilation_check::compilation_context context; + + if (compilation_check_ptr_ && !compilation_check_ptr_->continue_compilation(context)) + { + const std::string error_message = + !context.error_message.empty() ? " Details: " + context.error_message : ""; + + set_error(make_error( + parser_error::e_parser, + token_t(), + "ERR011 - Internal compilation check failed." + error_message, + exprtk_error_location)); + + return true; + } + + return false; + } + inline expression_node_ptr parse_expression(precedence_level precedence = e_level00) { + if (halt_compilation_check()) + { + exprtk_debug(("halt_compilation_check() - parse_expression checkpoint 2\n")); + return error_node(); + } + stack_limit_handler slh(*this); if (!slh) @@ -22211,6 +25173,11 @@ namespace exprtk return error_node(); } + if (token_is(token_t::e_eof,prsrhlpr_t::e_hold)) + { + return expression; + } + bool break_loop = false; state_t current_state; @@ -22221,110 +25188,111 @@ namespace exprtk switch (current_token().type) { - case token_t::e_assign : current_state.set(e_level00, e_level00, details::e_assign); break; - case token_t::e_addass : current_state.set(e_level00, e_level00, details::e_addass); break; - case token_t::e_subass : current_state.set(e_level00, e_level00, details::e_subass); break; - case token_t::e_mulass : current_state.set(e_level00, e_level00, details::e_mulass); break; - case token_t::e_divass : current_state.set(e_level00, e_level00, details::e_divass); break; - case token_t::e_modass : current_state.set(e_level00, e_level00, details::e_modass); break; - case token_t::e_swap : current_state.set(e_level00, e_level00, details::e_swap ); break; - case token_t::e_lt : current_state.set(e_level05, e_level06, details::e_lt ); break; - case token_t::e_lte : current_state.set(e_level05, e_level06, details::e_lte ); break; - case token_t::e_eq : current_state.set(e_level05, e_level06, details::e_eq ); break; - case token_t::e_ne : current_state.set(e_level05, e_level06, details::e_ne ); break; - case token_t::e_gte : current_state.set(e_level05, e_level06, details::e_gte ); break; - case token_t::e_gt : current_state.set(e_level05, e_level06, details::e_gt ); break; - case token_t::e_add : current_state.set(e_level07, e_level08, details::e_add ); break; - case token_t::e_sub : current_state.set(e_level07, e_level08, details::e_sub ); break; - case token_t::e_div : current_state.set(e_level10, e_level11, details::e_div ); break; - case token_t::e_mul : current_state.set(e_level10, e_level11, details::e_mul ); break; - case token_t::e_mod : current_state.set(e_level10, e_level11, details::e_mod ); break; - case token_t::e_pow : current_state.set(e_level12, e_level12, details::e_pow ); break; - default : if (token_t::e_symbol == current_token().type) - { - static const std::string s_and = "and" ; - static const std::string s_nand = "nand" ; - static const std::string s_or = "or" ; - static const std::string s_nor = "nor" ; - static const std::string s_xor = "xor" ; - static const std::string s_xnor = "xnor" ; - static const std::string s_in = "in" ; - static const std::string s_like = "like" ; - static const std::string s_ilike = "ilike"; - static const std::string s_and1 = "&" ; - static const std::string s_or1 = "|" ; - static const std::string s_not = "not" ; - - if (details::imatch(current_token().value,s_and)) - { - current_state.set(e_level03, e_level04, details::e_and); - break; - } - else if (details::imatch(current_token().value,s_and1)) - { - #ifndef exprtk_disable_sc_andor - current_state.set(e_level03, e_level04, details::e_scand); - #else - current_state.set(e_level03, e_level04, details::e_and); - #endif - break; - } - else if (details::imatch(current_token().value,s_nand)) - { - current_state.set(e_level03, e_level04, details::e_nand); - break; - } - else if (details::imatch(current_token().value,s_or)) - { - current_state.set(e_level01, e_level02, details::e_or); - break; - } - else if (details::imatch(current_token().value,s_or1)) - { - #ifndef exprtk_disable_sc_andor - current_state.set(e_level01, e_level02, details::e_scor); - #else - current_state.set(e_level01, e_level02, details::e_or); - #endif - break; - } - else if (details::imatch(current_token().value,s_nor)) - { - current_state.set(e_level01, e_level02, details::e_nor); - break; - } - else if (details::imatch(current_token().value,s_xor)) - { - current_state.set(e_level01, e_level02, details::e_xor); - break; - } - else if (details::imatch(current_token().value,s_xnor)) - { - current_state.set(e_level01, e_level02, details::e_xnor); - break; - } - else if (details::imatch(current_token().value,s_in)) - { - current_state.set(e_level04, e_level04, details::e_in); - break; - } - else if (details::imatch(current_token().value,s_like)) - { - current_state.set(e_level04, e_level04, details::e_like); - break; - } - else if (details::imatch(current_token().value,s_ilike)) - { - current_state.set(e_level04, e_level04, details::e_ilike); - break; - } - else if (details::imatch(current_token().value,s_not)) - { - break; - } - } - - break_loop = true; + case token_t::e_assign : current_state.set(e_level00, e_level00, details::e_assign, current_token()); break; + case token_t::e_addass : current_state.set(e_level00, e_level00, details::e_addass, current_token()); break; + case token_t::e_subass : current_state.set(e_level00, e_level00, details::e_subass, current_token()); break; + case token_t::e_mulass : current_state.set(e_level00, e_level00, details::e_mulass, current_token()); break; + case token_t::e_divass : current_state.set(e_level00, e_level00, details::e_divass, current_token()); break; + case token_t::e_modass : current_state.set(e_level00, e_level00, details::e_modass, current_token()); break; + case token_t::e_swap : current_state.set(e_level00, e_level00, details::e_swap , current_token()); break; + case token_t::e_lt : current_state.set(e_level05, e_level06, details::e_lt , current_token()); break; + case token_t::e_lte : current_state.set(e_level05, e_level06, details::e_lte , current_token()); break; + case token_t::e_eq : current_state.set(e_level05, e_level06, details::e_eq , current_token()); break; + case token_t::e_ne : current_state.set(e_level05, e_level06, details::e_ne , current_token()); break; + case token_t::e_gte : current_state.set(e_level05, e_level06, details::e_gte , current_token()); break; + case token_t::e_gt : current_state.set(e_level05, e_level06, details::e_gt , current_token()); break; + case token_t::e_add : current_state.set(e_level07, e_level08, details::e_add , current_token()); break; + case token_t::e_sub : current_state.set(e_level07, e_level08, details::e_sub , current_token()); break; + case token_t::e_div : current_state.set(e_level10, e_level11, details::e_div , current_token()); break; + case token_t::e_mul : current_state.set(e_level10, e_level11, details::e_mul , current_token()); break; + case token_t::e_mod : current_state.set(e_level10, e_level11, details::e_mod , current_token()); break; + case token_t::e_pow : current_state.set(e_level12, e_level12, details::e_pow , current_token()); break; + default : + if (token_t::e_symbol == current_token().type) + { + static const std::string s_and = "and" ; + static const std::string s_nand = "nand" ; + static const std::string s_or = "or" ; + static const std::string s_nor = "nor" ; + static const std::string s_xor = "xor" ; + static const std::string s_xnor = "xnor" ; + static const std::string s_in = "in" ; + static const std::string s_like = "like" ; + static const std::string s_ilike = "ilike"; + static const std::string s_and1 = "&" ; + static const std::string s_or1 = "|" ; + static const std::string s_not = "not" ; + + if (details::imatch(current_token().value,s_and)) + { + current_state.set(e_level03, e_level04, details::e_and, current_token()); + break; + } + else if (details::imatch(current_token().value,s_and1)) + { + #ifndef exprtk_disable_sc_andor + current_state.set(e_level03, e_level04, details::e_scand, current_token()); + #else + current_state.set(e_level03, e_level04, details::e_and, current_token()); + #endif + break; + } + else if (details::imatch(current_token().value,s_nand)) + { + current_state.set(e_level03, e_level04, details::e_nand, current_token()); + break; + } + else if (details::imatch(current_token().value,s_or)) + { + current_state.set(e_level01, e_level02, details::e_or, current_token()); + break; + } + else if (details::imatch(current_token().value,s_or1)) + { + #ifndef exprtk_disable_sc_andor + current_state.set(e_level01, e_level02, details::e_scor, current_token()); + #else + current_state.set(e_level01, e_level02, details::e_or, current_token()); + #endif + break; + } + else if (details::imatch(current_token().value,s_nor)) + { + current_state.set(e_level01, e_level02, details::e_nor, current_token()); + break; + } + else if (details::imatch(current_token().value,s_xor)) + { + current_state.set(e_level01, e_level02, details::e_xor, current_token()); + break; + } + else if (details::imatch(current_token().value,s_xnor)) + { + current_state.set(e_level01, e_level02, details::e_xnor, current_token()); + break; + } + else if (details::imatch(current_token().value,s_in)) + { + current_state.set(e_level04, e_level04, details::e_in, current_token()); + break; + } + else if (details::imatch(current_token().value,s_like)) + { + current_state.set(e_level04, e_level04, details::e_like, current_token()); + break; + } + else if (details::imatch(current_token().value,s_ilike)) + { + current_state.set(e_level04, e_level04, details::e_ilike, current_token()); + break; + } + else if (details::imatch(current_token().value,s_not)) + { + break; + } + } + + break_loop = true; } if (break_loop) @@ -22344,49 +25312,49 @@ namespace exprtk if (is_invalid_logic_operation(current_state.operation)) { - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); - set_error( - make_error(parser_error::e_syntax, - prev_token, - "ERR010 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + prev_token, + "ERR012 - Invalid or disabled logic operation '" + details::to_str(current_state.operation) + "'", + exprtk_error_location)); return error_node(); } else if (is_invalid_arithmetic_operation(current_state.operation)) { - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); - set_error( - make_error(parser_error::e_syntax, - prev_token, - "ERR011 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + prev_token, + "ERR013 - Invalid or disabled arithmetic operation '" + details::to_str(current_state.operation) + "'", + exprtk_error_location)); return error_node(); } else if (is_invalid_inequality_operation(current_state.operation)) { - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); - set_error( - make_error(parser_error::e_syntax, - prev_token, - "ERR012 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + prev_token, + "ERR014 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'", + exprtk_error_location)); return error_node(); } else if (is_invalid_assignment_operation(current_state.operation)) { - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); - set_error( - make_error(parser_error::e_syntax, - prev_token, - "ERR013 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + prev_token, + "ERR015 - Invalid or disabled assignment operation '" + details::to_str(current_state.operation) + "'", + exprtk_error_location)); return error_node(); } @@ -22401,34 +25369,38 @@ namespace exprtk free_node(node_allocator_, expression ); free_node(node_allocator_, right_branch); - set_error( - make_error(parser_error::e_syntax, - prev_token, - "ERR014 - Return statements cannot be part of sub-expressions", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + prev_token, + "ERR016 - Return statements cannot be part of sub-expressions", + exprtk_error_location)); return error_node(); } + push_current_state(current_state); + new_expression = expression_generator_ ( current_state.operation, expression, right_branch ); + + pop_current_state(); } if (0 == new_expression) { if (error_list_.empty()) { - set_error( - make_error(parser_error::e_syntax, - prev_token, - !synthesis_error_.empty() ? - synthesis_error_ : - "ERR015 - General parsing error at token: '" + prev_token.value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + prev_token, + !synthesis_error_.empty() ? + synthesis_error_ : + "ERR017 - General parsing error at token: '" + prev_token.value + "'", + exprtk_error_location)); } free_node(node_allocator_, expression ); @@ -22454,14 +25426,35 @@ namespace exprtk if ((0 != expression) && (expression->node_depth() > settings_.max_node_depth_)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR016 - Expression depth of " + details::to_str(static_cast(expression->node_depth())) + - " exceeds maximum allowed expression depth of " + details::to_str(static_cast(settings_.max_node_depth_)), - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR018 - Expression depth of " + details::to_str(static_cast(expression->node_depth())) + + " exceeds maximum allowed expression depth of " + details::to_str(static_cast(settings_.max_node_depth_)), + exprtk_error_location)); - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); + + return error_node(); + } + else if ( + !settings_.commutative_check_enabled() && + !details::is_logic_opr(current_token().value) && + (current_state.operation == details::e_default) && + ( + current_token().type == token_t::e_symbol || + current_token().type == token_t::e_number || + current_token().type == token_t::e_string + ) + ) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR019 - Invalid syntax '" + current_token().value + "' possible missing operator or context", + exprtk_error_location)); + + free_node(node_allocator_, expression); return error_node(); } @@ -22479,7 +25472,7 @@ namespace exprtk { expression_node_ptr un_r = n->branch(0); n->release(); - free_node(node_allocator_,node); + free_node(node_allocator_, node); node = un_r; return true; @@ -22501,20 +25494,20 @@ namespace exprtk (0 != (return_node = sem_ .get_variable(v))) ) { - free_node(node_allocator_,node); + free_node(node_allocator_, node); node = return_node; return true; } else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR017 - Failed to find variable node in symbol table", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR020 - Failed to find variable node in symbol table", + exprtk_error_location)); - free_node(node_allocator_,node); + free_node(node_allocator_, node); return false; } @@ -22610,6 +25603,7 @@ namespace exprtk { for (std::size_t i = 0; i < deq_.size(); ++i) { + exprtk_debug(("~scoped_deq_delete() - deleting node: %p\n", reinterpret_cast(deq_[i]))); free_node(parser_.node_allocator_,deq_[i]); } @@ -22644,6 +25638,7 @@ namespace exprtk { for (std::size_t i = 0; i < vec_.size(); ++i) { + exprtk_debug(("~scoped_vec_delete() - deleting node: %p\n", reinterpret_cast(vec_[i]))); free_node(parser_.node_allocator_,vec_[i]); } @@ -22651,6 +25646,11 @@ namespace exprtk } } + ptr_t operator[](const std::size_t index) + { + return vec_[index]; + } + bool delete_ptr; parser& parser_; std::vector& vec_; @@ -22732,11 +25732,11 @@ namespace exprtk case 19 : func_node = parse_function_call<19>(function,function_name); break; case 20 : func_node = parse_function_call<20>(function,function_name); break; default : { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR018 - Invalid number of parameters for function: '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR021 - Invalid number of parameters for function: '" + function_name + "'", + exprtk_error_location)); return error_node(); } @@ -22746,11 +25746,11 @@ namespace exprtk return func_node; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR019 - Failed to generate call to function: '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR022 - Failed to generate call to function: '" + function_name + "'", + exprtk_error_location)); return error_node(); } @@ -22765,11 +25765,11 @@ namespace exprtk #endif if (0 == NumberofParameters) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR020 - Expecting ifunction '" + function_name + "' to have non-zero parameter count", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR023 - Expecting ifunction '" + function_name + "' to have non-zero parameter count", + exprtk_error_location)); return error_node(); } @@ -22788,11 +25788,11 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR021 - Expecting argument list for function: '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR024 - Expecting argument list for function: '" + function_name + "'", + exprtk_error_location)); return error_node(); } @@ -22803,11 +25803,11 @@ namespace exprtk if (0 == branch[i]) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR022 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR025 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'", + exprtk_error_location)); return error_node(); } @@ -22815,11 +25815,11 @@ namespace exprtk { if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR023 - Invalid number of arguments for function: '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR026 - Invalid number of arguments for function: '" + function_name + "'", + exprtk_error_location)); return error_node(); } @@ -22828,11 +25828,11 @@ namespace exprtk if (!token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR024 - Invalid number of arguments for function: '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR027 - Invalid number of arguments for function: '" + function_name + "'", + exprtk_error_location)); return error_node(); } @@ -22857,13 +25857,13 @@ namespace exprtk !token_is(token_t::e_rbracket) ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR025 - Expecting '()' to proceed call to function: '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR028 - Expecting '()' to proceed call to function: '" + function_name + "'", + exprtk_error_location)); - free_node(node_allocator_,result); + free_node(node_allocator_, result); return error_node(); } @@ -22882,23 +25882,23 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR026 - Expected a '(' at start of function call to '" + function_name + - "', instead got: '" + current_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR029 - Expected a '(' at start of function call to '" + function_name + + "', instead got: '" + current_token().value + "'", + exprtk_error_location)); return 0; } if (token_is(token_t::e_rbracket, e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR027 - Expected at least one input parameter for function call '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR030 - Expected at least one input parameter for function call '" + function_name + "'", + exprtk_error_location)); return 0; } @@ -22920,11 +25920,11 @@ namespace exprtk continue; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR028 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR031 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'", + exprtk_error_location)); return 0; } @@ -22932,11 +25932,11 @@ namespace exprtk if (sd.delete_ptr) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR029 - Invalid number of input parameters passed to function '" + function_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR032 - Invalid number of input parameters passed to function '" + function_name + "'", + exprtk_error_location)); return 0; } @@ -22955,11 +25955,11 @@ namespace exprtk if (0 == std::distance(itr_range.first,itr_range.second)) { - set_error( - make_error(parser_error::e_syntax, - diagnostic_token, - "ERR030 - No entry found for base operation: " + operation_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + diagnostic_token, + "ERR033 - No entry found for base operation: " + operation_name, + exprtk_error_location)); return error_node(); } @@ -23002,11 +26002,11 @@ namespace exprtk free_node(node_allocator_, param_list[i]); } - set_error( - make_error(parser_error::e_syntax, - diagnostic_token, - "ERR031 - Invalid number of input parameters for call to function: '" + operation_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + diagnostic_token, + "ERR034 - Invalid number of input parameters for call to function: '" + operation_name + "'", + exprtk_error_location)); return error_node(); } @@ -23022,47 +26022,52 @@ namespace exprtk if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR032 - Expected ',' between if-statement condition and consequent", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR035 - Expected ',' between if-statement condition and consequent", + exprtk_error_location)); + result = false; } else if (0 == (consequent = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR033 - Failed to parse consequent for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR036 - Failed to parse consequent for if-statement", + exprtk_error_location)); + result = false; } else if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR034 - Expected ',' between if-statement consequent and alternative", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR037 - Expected ',' between if-statement consequent and alternative", + exprtk_error_location)); + result = false; } else if (0 == (alternative = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR035 - Failed to parse alternative for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR038 - Failed to parse alternative for if-statement", + exprtk_error_location)); + result = false; } else if (!token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR036 - Expected ')' at the end of if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR039 - Expected ')' at the end of if-statement", + exprtk_error_location)); + result = false; } @@ -23076,15 +26081,30 @@ namespace exprtk { if (consq_is_str && alter_is_str) { - return expression_generator_ - .conditional_string(condition, consequent, alternative); + expression_node_ptr result_node = + expression_generator_ + .conditional_string(condition, consequent, alternative); + + if (result_node && result_node->valid()) + { + return result_node; + } + + set_error(make_error( + parser_error::e_synthesis, + current_token(), + "ERR040 - Failed to synthesize node: conditional_string", + exprtk_error_location)); + + free_node(node_allocator_, result_node); + return error_node(); } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR037 - Return types of if-statement differ: string/non-string", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR041 - Return types of if-statement differ: string/non-string", + exprtk_error_location)); result = false; } @@ -23104,11 +26124,11 @@ namespace exprtk .conditional_vector(condition, consequent, alternative); } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR038 - Return types of if-statement differ: vector/non-vector", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR042 - Return types of if-statement differ: vector/non-vector", + exprtk_error_location)); result = false; } @@ -23138,11 +26158,31 @@ namespace exprtk { if (0 == (consequent = parse_multi_sequence("if-statement-01"))) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR039 - Failed to parse body of consequent for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR043 - Failed to parse body of consequent for if-statement", + exprtk_error_location)); + + result = false; + } + else if + ( + !settings_.commutative_check_enabled() && + !token_is("else",prsrhlpr_t::e_hold) && + !token_is_loop(prsrhlpr_t::e_hold) && + !token_is_arithmetic_opr(prsrhlpr_t::e_hold) && + !token_is_right_bracket (prsrhlpr_t::e_hold) && + !token_is_ineq_opr (prsrhlpr_t::e_hold) && + !token_is(token_t::e_ternary,prsrhlpr_t::e_hold) && + !token_is(token_t::e_eof ,prsrhlpr_t::e_hold) + ) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR044 - Expected ';' at the end of the consequent for if-statement (1)", + exprtk_error_location)); result = false; } @@ -23159,24 +26199,24 @@ namespace exprtk if (0 != (consequent = parse_expression())) { - if (!token_is(token_t::e_eof)) + if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR040 - Expected ';' at the end of the consequent for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR045 - Expected ';' at the end of the consequent for if-statement (2)", + exprtk_error_location)); result = false; } } else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR041 - Failed to parse body of consequent for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR046 - Failed to parse body of consequent for if-statement", + exprtk_error_location)); result = false; } @@ -23184,19 +26224,27 @@ namespace exprtk if (result) { - if (details::imatch(current_token().value,"else")) + if ( + details::imatch(current_token().value,"else") || + (token_is(token_t::e_eof, prsrhlpr_t::e_hold) && peek_token_is("else")) + ) { next_token(); + if (details::imatch(current_token().value,"else")) + { + next_token(); + } + if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) { if (0 == (alternative = parse_multi_sequence("else-statement-01"))) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR042 - Failed to parse body of the 'else' for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR047 - Failed to parse body of the 'else' for if-statement", + exprtk_error_location)); result = false; } @@ -23205,35 +26253,39 @@ namespace exprtk { if (0 == (alternative = parse_conditional_statement())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR043 - Failed to parse body of if-else statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR048 - Failed to parse body of if-else statement", + exprtk_error_location)); result = false; } } else if (0 != (alternative = parse_expression())) { - if (!token_is(token_t::e_eof)) + if ( + !token_is(token_t::e_ternary , prsrhlpr_t::e_hold) && + !token_is(token_t::e_rcrlbracket, prsrhlpr_t::e_hold) && + !token_is(token_t::e_eof) + ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR044 - Expected ';' at the end of the 'else-if' for the if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR049 - Expected ';' at the end of the 'else-if' for the if-statement", + exprtk_error_location)); result = false; } } else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR045 - Failed to parse body of the 'else' for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR050 - Failed to parse body of the 'else' for if-statement", + exprtk_error_location)); result = false; } @@ -23254,11 +26306,11 @@ namespace exprtk .conditional_string(condition, consequent, alternative); } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR046 - Return types of if-statement differ: string/non-string", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR051 - Return types of if-statement differ: string/non-string", + exprtk_error_location)); result = false; } @@ -23278,11 +26330,11 @@ namespace exprtk .conditional_vector(condition, consequent, alternative); } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR047 - Return types of if-statement differ: vector/non-vector", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR052 - Return types of if-statement differ: vector/non-vector", + exprtk_error_location)); result = false; } @@ -23309,21 +26361,21 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR048 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR053 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'", + exprtk_error_location)); return error_node(); } else if (0 == (condition = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR049 - Failed to parse condition for if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR054 - Failed to parse condition for if-statement", + exprtk_error_location)); return error_node(); } @@ -23353,13 +26405,13 @@ namespace exprtk return parse_conditional_statement_02(condition); } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR050 - Invalid if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR055 - Invalid if-statement", + exprtk_error_location)); - free_node(node_allocator_,condition); + free_node(node_allocator_, condition); return error_node(); } @@ -23374,51 +26426,51 @@ namespace exprtk if (0 == condition) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR051 - Encountered invalid condition branch for ternary if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR056 - Encountered invalid condition branch for ternary if-statement", + exprtk_error_location)); return error_node(); } else if (!token_is(token_t::e_ternary)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR052 - Expected '?' after condition of ternary if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR057 - Expected '?' after condition of ternary if-statement", + exprtk_error_location)); result = false; } else if (0 == (consequent = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR053 - Failed to parse consequent for ternary if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR058 - Failed to parse consequent for ternary if-statement", + exprtk_error_location)); result = false; } else if (!token_is(token_t::e_colon)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR054 - Expected ':' between ternary if-statement consequent and alternative", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR059 - Expected ':' between ternary if-statement consequent and alternative", + exprtk_error_location)); result = false; } else if (0 == (alternative = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR055 - Failed to parse alternative for ternary if-statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR060 - Failed to parse alternative for ternary if-statement", + exprtk_error_location)); result = false; } @@ -23437,11 +26489,11 @@ namespace exprtk .conditional_string(condition, consequent, alternative); } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR056 - Return types of ternary differ: string/non-string", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR061 - Return types of ternary differ: string/non-string", + exprtk_error_location)); result = false; } @@ -23461,11 +26513,11 @@ namespace exprtk .conditional_vector(condition, consequent, alternative); } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR057 - Return types of ternary differ: vector/non-vector", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR062 - Return types of ternary differ: vector/non-vector", + exprtk_error_location)); result = false; } @@ -23488,11 +26540,11 @@ namespace exprtk { if (settings_.logic_disabled("not")) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR058 - Invalid or disabled logic operation 'not'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR063 - Invalid or disabled logic operation 'not'", + exprtk_error_location)); return error_node(); } @@ -23519,31 +26571,31 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR059 - Expected '(' at start of while-loop condition statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR064 - Expected '(' at start of while-loop condition statement", + exprtk_error_location)); return error_node(); } else if (0 == (condition = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR060 - Failed to parse condition for while-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR065 - Failed to parse condition for while-loop", + exprtk_error_location)); return error_node(); } else if (!token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR061 - Expected ')' at end of while-loop condition statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR066 - Expected ')' at end of while-loop condition statement", + exprtk_error_location)); result = false; } @@ -23556,21 +26608,21 @@ namespace exprtk if (0 == (branch = parse_multi_sequence("while-loop", true))) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR062 - Failed to parse body of while-loop")); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR067 - Failed to parse body of while-loop")); result = false; } else if (0 == (result_node = expression_generator_.while_loop(condition, branch, brkcnt_list_.front()))) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR063 - Failed to synthesize while-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR068 - Failed to synthesize while-loop", + exprtk_error_location)); result = false; } @@ -23587,7 +26639,20 @@ namespace exprtk return error_node(); } - return result_node; + if (result_node && result_node->valid()) + { + return result_node; + } + + set_error(make_error( + parser_error::e_synthesis, + current_token(), + "ERR069 - Failed to synthesize 'valid' while-loop", + exprtk_error_location)); + + free_node(node_allocator_, result_node); + + return error_node(); } inline expression_node_ptr parse_repeat_until_loop() @@ -23611,7 +26676,7 @@ namespace exprtk } else { - const token_t::token_type seperator = token_t::e_eof; + const token_t::token_type separator = token_t::e_eof; scope_handler sh(*this); @@ -23642,13 +26707,13 @@ namespace exprtk const bool is_next_until = peek_token_is(token_t::e_symbol) && peek_token_is("until"); - if (!token_is(seperator) && is_next_until) + if (!token_is(separator) && is_next_until) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR064 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR070 - Expected '" + token_t::to_str(separator) + "' in body of repeat until loop", + exprtk_error_location)); return error_node(); } @@ -23666,11 +26731,11 @@ namespace exprtk if (sdd.delete_ptr) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR065 - Failed to parse body of repeat until loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR071 - Failed to parse body of repeat until loop", + exprtk_error_location)); return error_node(); } @@ -23678,33 +26743,33 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR066 - Expected '(' before condition statement of repeat until loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR072 - Expected '(' before condition statement of repeat until loop", + exprtk_error_location)); - free_node(node_allocator_,branch); + free_node(node_allocator_, branch); return error_node(); } else if (0 == (condition = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR067 - Failed to parse condition for repeat until loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR073 - Failed to parse condition for repeat until loop", + exprtk_error_location)); - free_node(node_allocator_,branch); + free_node(node_allocator_, branch); return error_node(); } else if (!token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR068 - Expected ')' after condition of repeat until loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR074 - Expected ')' after condition of repeat until loop", + exprtk_error_location)); free_node(node_allocator_, branch ); free_node(node_allocator_, condition); @@ -23712,27 +26777,42 @@ namespace exprtk return error_node(); } - expression_node_ptr result; - - result = expression_generator_ - .repeat_until_loop(condition, branch, brkcnt_list_.front()); + expression_node_ptr result_node = + expression_generator_ + .repeat_until_loop( + condition, + branch, + brkcnt_list_.front()); - if (0 == result) + if (0 == result_node) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR069 - Failed to synthesize repeat until loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR075 - Failed to synthesize repeat until loop", + exprtk_error_location)); - free_node(node_allocator_,condition); + free_node(node_allocator_, condition); return error_node(); } handle_brkcnt_scope_exit(); - return result; + if (result_node && result_node->valid()) + { + return result_node; + } + + set_error(make_error( + parser_error::e_synthesis, + current_token(), + "ERR076 - Failed to synthesize 'valid' repeat until loop", + exprtk_error_location)); + + free_node(node_allocator_, result_node); + + return error_node(); } inline expression_node_ptr parse_for_loop() @@ -23751,11 +26831,11 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR070 - Expected '(' at start of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR077 - Expected '(' at start of for-loop", + exprtk_error_location)); return error_node(); } @@ -23771,21 +26851,21 @@ namespace exprtk if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR071 - Expected a variable at the start of initialiser section of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR078 - Expected a variable at the start of initialiser section of for-loop", + exprtk_error_location)); return error_node(); } else if (!peek_token_is(token_t::e_assign)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR072 - Expected variable assignment of initialiser section of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR079 - Expected variable assignment of initialiser section of for-loop", + exprtk_error_location)); return error_node(); } @@ -23796,11 +26876,11 @@ namespace exprtk if ((se->name == loop_counter_symbol) && se->active) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR073 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR080 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration", + exprtk_error_location)); return error_node(); } @@ -23828,11 +26908,11 @@ namespace exprtk if (!sem_.add_element(nse)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR074 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR081 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM", + exprtk_error_location)); sem_.free_element(nse); @@ -23840,7 +26920,7 @@ namespace exprtk } else { - exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n",nse.name.c_str())); + exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n", nse.name.c_str())); state_.activate_side_effect("parse_for_loop()"); } @@ -23850,21 +26930,21 @@ namespace exprtk if (0 == (initialiser = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR075 - Failed to parse initialiser of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR082 - Failed to parse initialiser of for-loop", + exprtk_error_location)); result = false; } else if (!token_is(token_t::e_eof)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR076 - Expected ';' after initialiser of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR083 - Expected ';' after initialiser of for-loop", + exprtk_error_location)); result = false; } @@ -23874,21 +26954,21 @@ namespace exprtk { if (0 == (condition = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR077 - Failed to parse condition of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR084 - Failed to parse condition of for-loop", + exprtk_error_location)); result = false; } else if (!token_is(token_t::e_eof)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR078 - Expected ';' after condition section of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR085 - Expected ';' after condition section of for-loop", + exprtk_error_location)); result = false; } @@ -23898,21 +26978,21 @@ namespace exprtk { if (0 == (incrementor = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR079 - Failed to parse incrementor of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR086 - Failed to parse incrementor of for-loop", + exprtk_error_location)); result = false; } else if (!token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR080 - Expected ')' after incrementor section of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR087 - Expected ')' after incrementor section of for-loop", + exprtk_error_location)); result = false; } @@ -23926,11 +27006,11 @@ namespace exprtk if (0 == (loop_body = parse_multi_sequence("for-loop", true))) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR081 - Failed to parse body of for-loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR088 - Failed to parse body of for-loop", + exprtk_error_location)); result = false; } @@ -23958,7 +27038,20 @@ namespace exprtk brkcnt_list_.front()); handle_brkcnt_scope_exit(); - return result_node; + if (result_node && result_node->valid()) + { + return result_node; + } + + set_error(make_error( + parser_error::e_synthesis, + current_token(), + "ERR089 - Failed to synthesize 'valid' for-loop", + exprtk_error_location)); + + free_node(node_allocator_, result_node); + + return error_node(); } inline expression_node_ptr parse_switch_statement() @@ -23968,11 +27061,11 @@ namespace exprtk if (!details::imatch(current_token().value,"switch")) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR082 - Expected keyword 'switch'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR090 - Expected keyword 'switch'", + exprtk_error_location)); return error_node(); } @@ -23983,11 +27076,11 @@ namespace exprtk if (!token_is(token_t::e_lcrlbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR083 - Expected '{' for call to switch statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR091 - Expected '{' for call to switch statement", + exprtk_error_location)); return error_node(); } @@ -24008,18 +27101,21 @@ namespace exprtk return error_node(); else if (!token_is(token_t::e_colon)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR084 - Expected ':' for case of switch statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR092 - Expected ':' for case of switch statement", + exprtk_error_location)); free_node(node_allocator_, condition); return error_node(); } - expression_node_ptr consequent = parse_expression(); + expression_node_ptr consequent = + (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? + parse_multi_sequence("switch-consequent") : + parse_expression(); if (0 == consequent) { @@ -24029,11 +27125,11 @@ namespace exprtk } else if (!token_is(token_t::e_eof)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR085 - Expected ';' at end of case for switch statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR093 - Expected ';' at end of case for switch statement", + exprtk_error_location)); free_node(node_allocator_, condition ); free_node(node_allocator_, consequent); @@ -24058,11 +27154,11 @@ namespace exprtk { if (0 != default_statement) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR086 - Multiple default cases for switch statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR094 - Multiple default cases for switch statement", + exprtk_error_location)); return error_node(); } @@ -24071,29 +27167,29 @@ namespace exprtk if (!token_is(token_t::e_colon)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR087 - Expected ':' for default of switch statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR095 - Expected ':' for default of switch statement", + exprtk_error_location)); return error_node(); } - if (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) - default_statement = parse_multi_sequence("switch-default"); - else - default_statement = parse_expression(); + default_statement = + (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? + parse_multi_sequence("switch-default"): + parse_expression(); if (0 == default_statement) return error_node(); else if (!token_is(token_t::e_eof)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR088 - Expected ';' at end of default for switch statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR096 - Expected ';' at end of default for switch statement", + exprtk_error_location)); return error_node(); } @@ -24102,11 +27198,11 @@ namespace exprtk break; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR089 - Expected '}' at end of switch statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR097 - Expected '}' at end of switch statement", + exprtk_error_location)); return error_node(); } @@ -24118,6 +27214,10 @@ namespace exprtk { arg_list.push_back(default_statement); } + else + { + arg_list.push_back(node_allocator_.allocate_c(std::numeric_limits::quiet_NaN())); + } result = expression_generator_.switch_statement(arg_list, (0 != default_statement)); @@ -24133,11 +27233,11 @@ namespace exprtk if (!details::imatch(current_token().value,"[*]")) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR090 - Expected token '[*]'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR098 - Expected token '[*]'", + exprtk_error_location)); return error_node(); } @@ -24148,11 +27248,11 @@ namespace exprtk if (!token_is(token_t::e_lcrlbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR091 - Expected '{' for call to [*] statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR099 - Expected '{' for call to [*] statement", + exprtk_error_location)); return error_node(); } @@ -24161,11 +27261,11 @@ namespace exprtk { if (!details::imatch("case",current_token().value)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR092 - Expected a 'case' statement for multi-switch", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR100 - Expected a 'case' statement for multi-switch", + exprtk_error_location)); return error_node(); } @@ -24179,27 +27279,30 @@ namespace exprtk if (!token_is(token_t::e_colon)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR093 - Expected ':' for case of [*] statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR101 - Expected ':' for case of [*] statement", + exprtk_error_location)); return error_node(); } - expression_node_ptr consequent = parse_expression(); + expression_node_ptr consequent = + (token_is(token_t::e_lcrlbracket,prsrhlpr_t::e_hold)) ? + parse_multi_sequence("multi-switch-consequent") : + parse_expression(); if (0 == consequent) return error_node(); if (!token_is(token_t::e_eof)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR094 - Expected ';' at end of case for [*] statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR102 - Expected ';' at end of case for [*] statement", + exprtk_error_location)); return error_node(); } @@ -24224,11 +27327,11 @@ namespace exprtk if (!token_is(token_t::e_rcrlbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR095 - Expected '}' at end of [*] statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR103 - Expected '}' at end of [*] statement", + exprtk_error_location)); return error_node(); } @@ -24250,11 +27353,11 @@ namespace exprtk if (details::imatch(symbol,"~")) { next_token(); - return parse_multi_sequence(); + return check_block_statement_closure(parse_multi_sequence()); } else if (details::imatch(symbol,"[*]")) { - return parse_multi_switch_statement(); + return check_block_statement_closure(parse_multi_switch_statement()); } else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ; else if (details::imatch(symbol, "mand")) opt_type = details::e_mand; @@ -24265,11 +27368,11 @@ namespace exprtk else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR096 - Unsupported built-in vararg function: " + symbol, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR104 - Unsupported built-in vararg function: " + symbol, + exprtk_error_location)); return error_node(); } @@ -24282,23 +27385,23 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR097 - Expected '(' for call to vararg function: " + symbol, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR105 - Expected '(' for call to vararg function: " + symbol, + exprtk_error_location)); return error_node(); } if (token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR098 - vararg function: " + symbol + - " requires at least one input parameter", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR106 - vararg function: " + symbol + + " requires at least one input parameter", + exprtk_error_location)); return error_node(); } @@ -24316,11 +27419,11 @@ namespace exprtk break; else if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR099 - Expected ',' for call to vararg function: " + symbol, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR107 - Expected ',' for call to vararg function: " + symbol, + exprtk_error_location)); return error_node(); } @@ -24337,13 +27440,13 @@ namespace exprtk { if (!token_is(token_t::e_lsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR100 - Expected '[' as start of string range definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR108 - Expected '[' as start of string range definition", + exprtk_error_location)); - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); return error_node(); } @@ -24356,7 +27459,7 @@ namespace exprtk if (!parse_range(rp,true)) { - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); return error_node(); } @@ -24365,19 +27468,32 @@ namespace exprtk if (0 == result) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR101 - Failed to generate string range node", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR109 - Failed to generate string range node", + exprtk_error_location)); - free_node(node_allocator_,expression); + free_node(node_allocator_, expression); rp.free(); } rp.clear(); - return result; + if (result && result->valid()) + { + return result; + } + + set_error(make_error( + parser_error::e_synthesis, + current_token(), + "ERR110 - Failed to synthesize node: string_range_node", + exprtk_error_location)); + + free_node(node_allocator_, result); + rp.free(); + return error_node(); } #else inline expression_node_ptr parse_string_range_statement(expression_node_ptr&) @@ -24386,7 +27502,7 @@ namespace exprtk } #endif - inline void parse_pending_string_rangesize(expression_node_ptr& expression) + inline bool parse_pending_string_rangesize(expression_node_ptr& expression) { // Allow no more than 100 range calls, eg: s[][][]...[][] const std::size_t max_rangesize_parses = 100; @@ -24404,6 +27520,61 @@ namespace exprtk { expression = parse_string_range_statement(expression); } + + return (i > 1); + } + + inline void parse_pending_vector_index_operator(expression_node_ptr& expression) + { + if + ( + (0 != expression) && + error_list_.empty() && + is_ivector_node(expression) + ) + { + if ( + settings_.commutative_check_enabled() && + token_is(token_t::e_mul,prsrhlpr_t::e_hold) && + peek_token_is(token_t::e_lsqrbracket) + ) + { + token_is(token_t::e_mul); + token_is(token_t::e_lsqrbracket); + } + else if (token_is(token_t::e_lsqrbracket,prsrhlpr_t::e_hold)) + { + token_is(token_t::e_lsqrbracket); + } + else if ( + token_is(token_t::e_rbracket,prsrhlpr_t::e_hold) && + peek_token_is(token_t::e_lsqrbracket) + ) + { + token_is(token_t::e_rbracket ); + token_is(token_t::e_lsqrbracket); + } + else + return; + + details::vector_interface* vi = dynamic_cast*>(expression); + + if (vi) + { + details::vector_holder& vec = vi->vec()->vec_holder(); + const std::string vector_name = sem_.get_vector_name(vec.data()); + expression_node_ptr index = parse_vector_index(vector_name); + + if (index) + { + expression = synthesize_vector_element(vector_name, &vec, expression, index); + return; + } + } + + free_node(node_allocator_, expression); + expression = error_node(); + } } template tmp_expression_list; + exprtk_debug(("simplify() - expression_list.size: %d side_effect_list.size(): %d\n", + static_cast(expression_list .size()), + static_cast(side_effect_list.size()))); + bool return_node_present = false; for (std::size_t i = 0; i < (expression_list.size() - 1); ++i) @@ -24439,7 +27614,7 @@ namespace exprtk for (std::size_t j = i + 1; j < expression_list.size(); ++j) { - free_node(node_allocator_,expression_list[j]); + free_node(node_allocator_, expression_list[j]); } return_node_present = true; @@ -24452,7 +27627,7 @@ namespace exprtk !side_effect_list[i] ) { - free_node(node_allocator_,expression_list[i]); + free_node(node_allocator_, expression_list[i]); continue; } else @@ -24493,7 +27668,7 @@ namespace exprtk { token_t::token_type open_bracket = token_t::e_lcrlbracket; token_t::token_type close_bracket = token_t::e_rcrlbracket; - token_t::token_type seperator = token_t::e_eof; + token_t::token_type separator = token_t::e_eof; if (!token_is(open_bracket)) { @@ -24501,16 +27676,16 @@ namespace exprtk { open_bracket = token_t::e_lbracket; close_bracket = token_t::e_rbracket; - seperator = token_t::e_comma; + separator = token_t::e_comma; } else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR102 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" + - ((!source.empty()) ? std::string(" section of " + source): ""), - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR111 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" + + ((!source.empty()) ? std::string(" section of " + source): ""), + exprtk_error_location)); return error_node(); } @@ -24550,13 +27725,13 @@ namespace exprtk const bool is_next_close = peek_token_is(close_bracket); - if (!token_is(seperator) && is_next_close) + if (!token_is(separator) && is_next_close) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR103 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR112 - Expected '" + lexer::token::seperator_to_str(separator) + "' for call to multi-sequence section of " + source, + exprtk_error_location)); return error_node(); } @@ -24574,23 +27749,23 @@ namespace exprtk inline bool parse_range(range_t& rp, const bool skip_lsqr = false) { // Examples of valid ranges: - // 1. [1:5] -> 1..5 - // 2. [ :5] -> 0..5 - // 3. [1: ] -> 1..end - // 4. [x:y] -> x..y where x <= y - // 5. [x+1:y/2] -> x+1..y/2 where x+1 <= y/2 - // 6. [ :y] -> 0..y where 0 <= y - // 7. [x: ] -> x..end where x <= end + // 1. [1:5] -> [1,5) + // 2. [ :5] -> [0,5) + // 3. [1: ] -> [1,end) + // 4. [x:y] -> [x,y) where x <= y + // 5. [x+1:y/2] -> [x+1,y/2) where x+1 <= y/2 + // 6. [ :y] -> [0,y) where 0 <= y + // 7. [x: ] -> [x,end) where x <= end rp.clear(); if (!skip_lsqr && !token_is(token_t::e_lsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR104 - Expected '[' for start of range", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR113 - Expected '[' for start of range", + exprtk_error_location)); return false; } @@ -24607,11 +27782,11 @@ namespace exprtk if (0 == r0) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR105 - Failed parse begin section of range", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR114 - Failed parse begin section of range", + exprtk_error_location)); return false; } @@ -24626,15 +27801,15 @@ namespace exprtk rp.cache.first = rp.n0_c.second; } - free_node(node_allocator_,r0); + free_node(node_allocator_, r0); if (r0_value < T(0)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR106 - Range lower bound less than zero! Constraint: r0 >= 0", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR115 - Range lower bound less than zero! Constraint: r0 >= 0", + exprtk_error_location)); return false; } @@ -24647,11 +27822,11 @@ namespace exprtk if (!token_is(token_t::e_colon)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR107 - Expected ':' for break in range", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR116 - Expected ':' for break in range", + exprtk_error_location)); rp.free(); @@ -24670,11 +27845,11 @@ namespace exprtk if (0 == r1) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR108 - Failed parse end section of range", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR117 - Failed parse end section of range", + exprtk_error_location)); rp.free(); @@ -24691,15 +27866,15 @@ namespace exprtk rp.cache.second = rp.n1_c.second; } - free_node(node_allocator_,r1); + free_node(node_allocator_, r1); if (r1_value < T(0)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR109 - Range upper bound less than zero! Constraint: r1 >= 0", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR118 - Range upper bound less than zero! Constraint: r1 >= 0", + exprtk_error_location)); rp.free(); @@ -24714,11 +27889,11 @@ namespace exprtk if (!token_is(token_t::e_rsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR110 - Expected ']' for start of range", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR119 - Expected ']' for start of range", + exprtk_error_location)); rp.free(); @@ -24742,11 +27917,11 @@ namespace exprtk if (!rp_result || (r0 > r1)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR111 - Invalid range, Constraint: r0 <= r1", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR120 - Invalid range, Constraint: r0 <= r1", + exprtk_error_location)); return false; } @@ -24786,11 +27961,11 @@ namespace exprtk if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR112 - Unknown string symbol", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR121 - Unknown string symbol", + exprtk_error_location)); return error_node(); } @@ -24826,7 +28001,7 @@ namespace exprtk if (const_str_node) { - free_node(node_allocator_,result); + free_node(node_allocator_, result); return expression_generator_(T(const_str_node->size())); } @@ -24839,13 +28014,13 @@ namespace exprtk if (!parse_range(rp)) { - free_node(node_allocator_,result); + free_node(node_allocator_, result); return error_node(); } else if (const_str_node) { - free_node(node_allocator_,result); + free_node(node_allocator_, result); result = expression_generator_(const_str_node->ref(),rp); } else @@ -24882,7 +28057,7 @@ namespace exprtk next_token(); next_token(); - free_node(node_allocator_,result); + free_node(node_allocator_, result); return expression_generator_(T(const_str.size())); } @@ -24891,13 +28066,13 @@ namespace exprtk if (!parse_range(rp)) { - free_node(node_allocator_,result); + free_node(node_allocator_, result); rp.free(); return error_node(); } - free_node(node_allocator_,result); + free_node(node_allocator_, result); if (rp.n1_c.first && (rp.n1_c.second == std::numeric_limits::max())) { @@ -24910,13 +28085,13 @@ namespace exprtk (rp.n1_c.first && (rp.n1_c.second >= const_str.size())) ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR113 - Overflow in range for string: '" + const_str + "'[" + - (rp.n0_c.first ? details::to_str(static_cast(rp.n0_c.second)) : "?") + ":" + - (rp.n1_c.first ? details::to_str(static_cast(rp.n1_c.second)) : "?") + "]", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR122 - Overflow in range for string: '" + const_str + "'[" + + (rp.n0_c.first ? details::to_str(static_cast(rp.n0_c.second)) : "?") + ":" + + (rp.n1_c.first ? details::to_str(static_cast(rp.n1_c.second)) : "?") + "]", + exprtk_error_location)); rp.free(); @@ -24940,30 +28115,60 @@ namespace exprtk } #endif + inline expression_node_ptr parse_vector_index(const std::string& vector_name = "") + { + expression_node_ptr index_expr = error_node(); + + if (0 == (index_expr = parse_expression())) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR123 - Failed to parse index for vector: '" + vector_name + "'", + exprtk_error_location)); + + return error_node(); + } + else if (!token_is(token_t::e_rsqrbracket)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR124 - Expected ']' for index of vector: '" + vector_name + "'", + exprtk_error_location)); + + free_node(node_allocator_, index_expr); + + return error_node(); + } + + return index_expr; + } + inline expression_node_ptr parse_vector() { - const std::string symbol = current_token().value; + const std::string vector_name = current_token().value; vector_holder_ptr vec = vector_holder_ptr(0); - const scope_element& se = sem_.get_active_element(symbol); + const scope_element& se = sem_.get_active_element(vector_name); if ( - !details::imatch(se.name, symbol) || + !details::imatch(se.name, vector_name) || (se.depth > state_.scope_depth) || (scope_element::e_vector != se.type) ) { typedef typename symtab_store::vector_context vec_ctxt_t; - vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(symbol); + vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(vector_name); if (0 == vec_ctx.vector_holder) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR114 - Symbol '" + symbol+ " not a vector", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR125 - Symbol '" + vector_name + " not a vector", + exprtk_error_location)); return error_node(); } @@ -24981,12 +28186,12 @@ namespace exprtk } } else + { vec = se.vec_node; + } assert(0 != vec); - expression_node_ptr index_expr = error_node(); - next_token(); if (!token_is(token_t::e_lsqrbracket)) @@ -24995,31 +28200,28 @@ namespace exprtk } else if (token_is(token_t::e_rsqrbracket)) { - return expression_generator_(T(vec->size())); + return (vec->rebaseable()) ? + node_allocator_.allocate(vec) : + expression_generator_(T(vec->size())); } - else if (0 == (index_expr = parse_expression())) - { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR115 - Failed to parse index for vector: '" + symbol + "'", - exprtk_error_location)); - return error_node(); - } - else if (!token_is(token_t::e_rsqrbracket)) - { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR116 - Expected ']' for index of vector: '" + symbol + "'", - exprtk_error_location)); + expression_node_ptr index_expr = parse_vector_index(vector_name); - free_node(node_allocator_,index_expr); + if (index_expr) + { + expression_node_ptr vec_node = node_allocator_.allocate(vec); - return error_node(); + return synthesize_vector_element(vector_name, vec, vec_node, index_expr); } + return error_node(); + } + + inline expression_node_ptr synthesize_vector_element(const std::string& vector_name, + vector_holder_ptr vec, + expression_node_ptr vec_node, + expression_node_ptr index_expr) + { // Perform compile-time range check if (details::is_constant_node(index_expr)) { @@ -25028,20 +28230,21 @@ namespace exprtk if (index >= vec_size) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR117 - Index of " + details::to_str(index) + " out of range for " - "vector '" + symbol + "' of size " + details::to_str(vec_size), - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR126 - Index of " + details::to_str(index) + " out of range for " + "vector '" + vector_name + "' of size " + details::to_str(vec_size), + exprtk_error_location)); - free_node(node_allocator_,index_expr); + free_node(node_allocator_, vec_node ); + free_node(node_allocator_, index_expr); return error_node(); } } - return expression_generator_.vector_element(symbol, vec, index_expr); + return expression_generator_.vector_element(vector_name, vec, vec_node, index_expr); } inline expression_node_ptr parse_vararg_function_call(ivararg_function* vararg_function, const std::string& vararg_function_name) @@ -25060,12 +28263,12 @@ namespace exprtk { if (!vararg_function->allow_zero_parameters()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR118 - Zero parameter call to vararg function: " - + vararg_function_name + " not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR127 - Zero parameter call to vararg function: " + + vararg_function_name + " not allowed", + exprtk_error_location)); return error_node(); } @@ -25085,12 +28288,12 @@ namespace exprtk break; else if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR119 - Expected ',' for call to vararg function: " - + vararg_function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR128 - Expected ',' for call to vararg function: " + + vararg_function_name, + exprtk_error_location)); return error_node(); } @@ -25099,37 +28302,37 @@ namespace exprtk } else if (!vararg_function->allow_zero_parameters()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR120 - Zero parameter call to vararg function: " - + vararg_function_name + " not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR129 - Zero parameter call to vararg function: " + + vararg_function_name + " not allowed", + exprtk_error_location)); return error_node(); } if (arg_list.size() < vararg_function->min_num_args()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR121 - Invalid number of parameters to call to vararg function: " - + vararg_function_name + ", require at least " - + details::to_str(static_cast(vararg_function->min_num_args())) + " parameters", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR130 - Invalid number of parameters to call to vararg function: " + + vararg_function_name + ", require at least " + + details::to_str(static_cast(vararg_function->min_num_args())) + " parameters", + exprtk_error_location)); return error_node(); } else if (arg_list.size() > vararg_function->max_num_args()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR122 - Invalid number of parameters to call to vararg function: " - + vararg_function_name + ", require no more than " - + details::to_str(static_cast(vararg_function->max_num_args())) + " parameters", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR131 - Invalid number of parameters to call to vararg function: " + + vararg_function_name + ", require no more than " + + details::to_str(static_cast(vararg_function->max_num_args())) + " parameters", + exprtk_error_location)); return error_node(); } @@ -25200,14 +28403,13 @@ namespace exprtk if (1 == error_list.size()) { - parser_. - set_error( - make_error(parser_error::e_syntax, - parser_.current_token(), - "ERR123 - Failed parameter type check for function '" + function_name_ + "', " - "Expected '" + function_definition_list_[0].param_seq + - "' call set: '" + param_seq + "'", - exprtk_error_location)); + parser_.set_error(make_error( + parser_error::e_syntax, + parser_.current_token(), + "ERR132 - Failed parameter type check for function '" + function_name_ + "', " + "Expected '" + function_definition_list_[0].param_seq + + "' call set: '" + param_seq + "'", + exprtk_error_location)); } else { @@ -25222,14 +28424,13 @@ namespace exprtk } } - parser_. - set_error( - make_error(parser_error::e_syntax, - parser_.current_token(), - "ERR124 - Failed parameter type check for function '" + function_name_ + "', " - "Best match: '" + function_definition_list_[max_diff_index].param_seq + - "' call set: '" + param_seq + "'", - exprtk_error_location)); + parser_.set_error(make_error( + parser_error::e_syntax, + parser_.current_token(), + "ERR133 - Failed parameter type check for function '" + function_name_ + "', " + "Best match: '" + function_definition_list_[max_diff_index].param_seq + + "' call set: '" + param_seq + "'", + exprtk_error_location)); } return false; @@ -25364,13 +28565,12 @@ namespace exprtk { invalid_state_ = false; - parser_. - set_error( - make_error(parser_error::e_syntax, - parser_.current_token(), - "ERR125 - Invalid parameter sequence of '" + param_seq_list[i] + - "' for function: " + function_name_, - exprtk_error_location)); + parser_.set_error(make_error( + parser_error::e_syntax, + parser_.current_token(), + "ERR134 - Invalid parameter sequence of '" + param_seq_list[i] + + "' for function: " + function_name_, + exprtk_error_location)); return; } @@ -25380,15 +28580,14 @@ namespace exprtk { invalid_state_ = false; - parser_. - set_error( - make_error(parser_error::e_syntax, - parser_.current_token(), - "ERR126 - Function '" + function_name_ + "' has a parameter sequence conflict between " + - "pseq_idx[" + details::to_str(seq_itr->second) + "] and" + - "pseq_idx[" + details::to_str(i) + "] " + - "param seq: " + param_seq_list[i], - exprtk_error_location)); + parser_.set_error(make_error( + parser_error::e_syntax, + parser_.current_token(), + "ERR135 - Function '" + function_name_ + "' has a parameter sequence conflict between " + + "pseq_idx[" + details::to_str(seq_itr->second) + "] and" + + "pseq_idx[" + details::to_str(i) + "] " + + "param seq: " + param_seq_list[i], + exprtk_error_location)); return; } @@ -25424,11 +28623,11 @@ namespace exprtk if (tc.invalid()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR127 - Type checker instantiation failure for generic function: " + function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR136 - Type checker instantiation failure for generic function: " + function_name, + exprtk_error_location)); return error_node(); } @@ -25442,12 +28641,12 @@ namespace exprtk !tc .allow_zero_parameters() ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR128 - Zero parameter call to generic function: " - + function_name + " not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR137 - Zero parameter call to generic function: " + + function_name + " not allowed", + exprtk_error_location)); return error_node(); } @@ -25474,11 +28673,11 @@ namespace exprtk break; else if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR129 - Expected ',' for call to generic function: " + function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR138 - Expected ',' for call to generic function: " + function_name, + exprtk_error_location)); return error_node(); } @@ -25491,12 +28690,12 @@ namespace exprtk !tc .allow_zero_parameters () ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR130 - Zero parameter call to generic function: " - + function_name + " not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR139 - Zero parameter call to generic function: " + + function_name + " not allowed", + exprtk_error_location)); return error_node(); } @@ -25508,22 +28707,21 @@ namespace exprtk !tc.verify(param_type_list, param_seq_index) ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR131 - Invalid input parameter sequence for call to generic function: " + function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR140 - Invalid input parameter sequence for call to generic function: " + function_name, + exprtk_error_location)); return error_node(); } expression_node_ptr result = error_node(); - if (tc.paramseq_count() <= 1) - result = expression_generator_ - .generic_function_call(function, arg_list); - else - result = expression_generator_ + result = (tc.paramseq_count() <= 1) ? + expression_generator_ + .generic_function_call(function, arg_list) : + expression_generator_ .generic_function_call(function, arg_list, param_seq_index); sdd.delete_ptr = (0 == result); @@ -25546,12 +28744,12 @@ namespace exprtk !tc .allow_zero_parameters() ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR132 - Zero parameter call to generic function: " - + function_name + " not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR141 - Zero parameter call to generic function: " + + function_name + " not allowed", + exprtk_error_location)); return false; } @@ -25578,11 +28776,11 @@ namespace exprtk break; else if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR133 - Expected ',' for call to string function: " + function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR142 - Expected ',' for call to string function: " + function_name, + exprtk_error_location)); return false; } @@ -25625,22 +28823,21 @@ namespace exprtk if (!tc.verify(param_type_list, param_seq_index)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR134 - Invalid input parameter sequence for call to string function: " + function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR143 - Invalid input parameter sequence for call to string function: " + function_name, + exprtk_error_location)); return error_node(); } expression_node_ptr result = error_node(); - if (tc.paramseq_count() <= 1) - result = expression_generator_ - .string_function_call(function, arg_list); - else - result = expression_generator_ + result = (tc.paramseq_count() <= 1) ? + expression_generator_ + .string_function_call(function, arg_list) : + expression_generator_ .string_function_call(function, arg_list, param_seq_index); sdd.delete_ptr = (0 == result); @@ -25677,11 +28874,11 @@ namespace exprtk if (!tc.verify(param_type_list, param_seq_index)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR135 - Invalid input parameter sequence for call to overloaded function: " + function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR144 - Invalid input parameter sequence for call to overloaded function: " + function_name, + exprtk_error_location)); return error_node(); } @@ -25708,11 +28905,11 @@ namespace exprtk } else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR136 - Invalid return type for call to overloaded function: " + function_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR145 - Invalid return type for call to overloaded function: " + function_name, + exprtk_error_location)); } sdd.delete_ptr = (0 == result); @@ -25736,11 +28933,11 @@ namespace exprtk if (!p.token_is(token_t::e_lbracket)) { - p.set_error( - make_error(parser_error::e_syntax, - p.current_token(), - "ERR137 - Expected '(' for special function '" + sf_name + "'", - exprtk_error_location)); + p.set_error(make_error( + parser_error::e_syntax, + p.current_token(), + "ERR146 - Expected '(' for special function '" + sf_name + "'", + exprtk_error_location)); return error_node(); } @@ -25757,11 +28954,11 @@ namespace exprtk { if (!p.token_is(token_t::e_comma)) { - p.set_error( - make_error(parser_error::e_syntax, - p.current_token(), - "ERR138 - Expected ',' before next parameter of special function '" + sf_name + "'", - exprtk_error_location)); + p.set_error(make_error( + parser_error::e_syntax, + p.current_token(), + "ERR147 - Expected ',' before next parameter of special function '" + sf_name + "'", + exprtk_error_location)); return p.error_node(); } @@ -25770,11 +28967,11 @@ namespace exprtk if (!p.token_is(token_t::e_rbracket)) { - p.set_error( - make_error(parser_error::e_syntax, - p.current_token(), - "ERR139 - Invalid number of parameters for special function '" + sf_name + "'", - exprtk_error_location)); + p.set_error(make_error( + parser_error::e_syntax, + p.current_token(), + "ERR148 - Invalid number of parameters for special function '" + sf_name + "'", + exprtk_error_location)); return p.error_node(); } @@ -25797,11 +28994,11 @@ namespace exprtk !details::is_digit(sf_name[3]) ) { - set_error( - make_error(parser_error::e_token, - current_token(), - "ERR140 - Invalid special function[1]: " + sf_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_token, + current_token(), + "ERR149 - Invalid special function[1]: " + sf_name, + exprtk_error_location)); return error_node(); } @@ -25811,11 +29008,11 @@ namespace exprtk if (id >= details::e_sffinal) { - set_error( - make_error(parser_error::e_token, - current_token(), - "ERR141 - Invalid special function[2]: " + sf_name, - exprtk_error_location)); + set_error(make_error( + parser_error::e_token, + current_token(), + "ERR150 - Invalid special function[2]: " + sf_name, + exprtk_error_location)); return error_node(); } @@ -25843,21 +29040,21 @@ namespace exprtk { if (state_.parsing_break_stmt) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR142 - Invoking 'break' within a break call is not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR151 - Invoking 'break' within a break call is not allowed", + exprtk_error_location)); return error_node(); } else if (0 == state_.parsing_loop_stmt_count) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR143 - Invalid use of 'break', allowed only in the scope of a loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR152 - Invalid use of 'break', allowed only in the scope of a loop", + exprtk_error_location)); return error_node(); } @@ -25876,23 +29073,23 @@ namespace exprtk { if (0 == (return_expr = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR144 - Failed to parse return expression for 'break' statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR153 - Failed to parse return expression for 'break' statement", + exprtk_error_location)); return error_node(); } else if (!token_is(token_t::e_rsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR145 - Expected ']' at the completion of break's return expression", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR154 - Expected ']' at the completion of break's return expression", + exprtk_error_location)); - free_node(node_allocator_,return_expr); + free_node(node_allocator_, return_expr); return error_node(); } @@ -25904,11 +29101,11 @@ namespace exprtk } else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR146 - Invalid use of 'break', allowed only in the scope of a loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR155 - Invalid use of 'break', allowed only in the scope of a loop", + exprtk_error_location)); } return error_node(); @@ -25918,11 +29115,11 @@ namespace exprtk { if (0 == state_.parsing_loop_stmt_count) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR147 - Invalid use of 'continue', allowed only in the scope of a loop", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR156 - Invalid use of 'continue', allowed only in the scope of a loop", + exprtk_error_location)); return error_node(); } @@ -25940,123 +29137,222 @@ namespace exprtk inline expression_node_ptr parse_define_vector_statement(const std::string& vec_name) { - expression_node_ptr size_expr = error_node(); + expression_node_ptr size_expression_node = error_node(); if (!token_is(token_t::e_lsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR148 - Expected '[' as part of vector size definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR157 - Expected '[' as part of vector size definition", + exprtk_error_location)); return error_node(); } - else if (0 == (size_expr = parse_expression())) + else if (0 == (size_expression_node = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR149 - Failed to determine size of vector '" + vec_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR158 - Failed to determine size of vector '" + vec_name + "'", + exprtk_error_location)); return error_node(); } - else if (!is_constant_node(size_expr)) + else if (!is_constant_node(size_expression_node)) { - free_node(node_allocator_,size_expr); + const bool is_rebaseble_vector = + (size_expression_node->type() == details::expression_node::e_vecsize) && + static_cast*>(size_expression_node)->vec_holder()->rebaseable(); - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR150 - Expected a literal number as size of vector '" + vec_name + "'", - exprtk_error_location)); + free_node(node_allocator_, size_expression_node); + + const std::string error_msg = (is_rebaseble_vector) ? + std::string("Rebasable/Resizable vector cannot be used to define the size of vector") : + std::string("Expected a constant literal number as size of vector"); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR159 - " + error_msg + " '" + vec_name + "'", + exprtk_error_location)); return error_node(); } - const T vector_size = size_expr->value(); + const T vector_size = size_expression_node->value(); - free_node(node_allocator_,size_expr); + free_node(node_allocator_, size_expression_node); - const T max_vector_size = T(2000000000.0); + const std::size_t max_vector_size = settings_.max_local_vector_size(); if ( (vector_size <= T(0)) || std::not_equal_to() (T(0),vector_size - details::numeric::trunc(vector_size)) || - (vector_size > max_vector_size) + (static_cast(vector_size) > max_vector_size) ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR151 - Invalid vector size. Must be an integer in the range [0,2e9], size: " + - details::to_str(details::numeric::to_int32(vector_size)), - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR160 - Invalid vector size. Must be an integer in the " + "range [0," + details::to_str(static_cast(max_vector_size)) + "], size: " + + details::to_str(details::numeric::to_int32(vector_size)), + exprtk_error_location)); return error_node(); } + typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0); + + const std::size_t vec_size = static_cast(details::numeric::to_int32(vector_size)); + + scope_element& se = sem_.get_element(vec_name); + + if (se.name == vec_name) + { + if (se.active) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'", + exprtk_error_location)); + + return error_node(); + } + else if ( + (se.size == vec_size) && + (scope_element::e_vector == se.type) + ) + { + vec_holder = se.vec_node; + se.active = true; + se.depth = state_.scope_depth; + se.ref_count++; + } + } + + if (0 == vec_holder) + { + scope_element nse; + nse.name = vec_name; + nse.active = true; + nse.ref_count = 1; + nse.type = scope_element::e_vector; + nse.depth = state_.scope_depth; + nse.size = vec_size; + nse.data = new T[vec_size]; + nse.vec_node = new typename scope_element::vector_holder_t(reinterpret_cast(nse.data),nse.size); + + details::set_zero_value(reinterpret_cast(nse.data),vec_size); + + if (!sem_.add_element(nse)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM", + exprtk_error_location)); + + sem_.free_element(nse); + + return error_node(); + } + + vec_holder = nse.vec_node; + + exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n", + nse.name.c_str(), + static_cast(nse.size))); + } + + state_.activate_side_effect("parse_define_vector_statement()"); + + lodge_symbol(vec_name, e_st_local_vector); + std::vector vec_initilizer_list; scoped_vec_delete svd((*this),vec_initilizer_list); bool single_value_initialiser = false; + bool range_value_initialiser = false; bool vec_to_vec_initialiser = false; bool null_initialisation = false; if (!token_is(token_t::e_rsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR152 - Expected ']' as part of vector size definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR163 - Expected ']' as part of vector size definition", + exprtk_error_location)); return error_node(); } - else if (!token_is(token_t::e_eof)) + else if (!token_is(token_t::e_eof, prsrhlpr_t::e_hold)) { if (!token_is(token_t::e_assign)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR153 - Expected ':=' as part of vector definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR164 - Expected ':=' as part of vector definition", + exprtk_error_location)); return error_node(); } else if (token_is(token_t::e_lsqrbracket)) { - expression_node_ptr initialiser = parse_expression(); + expression_node_ptr initialiser_component = parse_expression(); - if (0 == initialiser) + if (0 == initialiser_component) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR154 - Failed to parse single vector initialiser", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR165 - Failed to parse first component of vector initialiser for vector: " + vec_name, + exprtk_error_location)); return error_node(); } - vec_initilizer_list.push_back(initialiser); + vec_initilizer_list.push_back(initialiser_component); + + if (token_is(token_t::e_colon)) + { + initialiser_component = parse_expression(); + + if (0 == initialiser_component) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR166 - Failed to parse second component of vector initialiser for vector: " + vec_name, + exprtk_error_location)); + + return error_node(); + } + + vec_initilizer_list.push_back(initialiser_component); + } if (!token_is(token_t::e_rsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR155 - Expected ']' to close single value vector initialiser", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR167 - Expected ']' to close single value vector initialiser", + exprtk_error_location)); return error_node(); } - single_value_initialiser = true; + switch (vec_initilizer_list.size()) + { + case 1 : single_value_initialiser = true; break; + case 2 : range_value_initialiser = true; break; + } } else if (!token_is(token_t::e_lcrlbracket)) { @@ -26066,9 +29362,9 @@ namespace exprtk if (token_t::e_symbol == current_token().type) { // Is it a locally defined vector? - const scope_element& se = sem_.get_active_element(current_token().value); + const scope_element& lcl_se = sem_.get_active_element(current_token().value); - if (scope_element::e_vector == se.type) + if (scope_element::e_vector == lcl_se.type) { if (0 != (initialiser = parse_expression())) vec_initilizer_list.push_back(initialiser); @@ -26094,11 +29390,11 @@ namespace exprtk { if (0 == initialiser) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR156 - Expected '{' as part of vector initialiser list", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR168 - Expected '{' as part of vector initialiser list", + exprtk_error_location)); return error_node(); } @@ -26114,11 +29410,11 @@ namespace exprtk if (0 == initialiser) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR157 - Expected '{' as part of vector initialiser list", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR169 - Expected '{' as part of vector initialiser list", + exprtk_error_location)); return error_node(); } @@ -26132,11 +29428,11 @@ namespace exprtk if (!token_is(token_t::e_comma) && is_next_close) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR158 - Expected ',' between vector initialisers", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR170 - Expected ',' between vector initialisers", + exprtk_error_location)); return error_node(); } @@ -26152,99 +29448,118 @@ namespace exprtk !token_is(token_t::e_rsqrbracket, prsrhlpr_t::e_hold) ) { - if (!token_is(token_t::e_eof)) + if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR159 - Expected ';' at end of vector definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR171 - Expected ';' at end of vector definition", + exprtk_error_location)); return error_node(); } } - if (T(vec_initilizer_list.size()) > vector_size) + if ( + !single_value_initialiser && + !range_value_initialiser && + (T(vec_initilizer_list.size()) > vector_size) + ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR160 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR172 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", + exprtk_error_location)); return error_node(); } } - typename symbol_table_t::vector_holder_ptr vec_holder = typename symbol_table_t::vector_holder_ptr(0); - - const std::size_t vec_size = static_cast(details::numeric::to_int32(vector_size)); - - scope_element& se = sem_.get_element(vec_name); + expression_node_ptr result = error_node(); - if (se.name == vec_name) + if ( + (vec_initilizer_list.size() == 1) && + single_value_initialiser + ) { - if (se.active) + if (details::is_constant_node(vec_initilizer_list[0])) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'", - exprtk_error_location)); - - return error_node(); + // vector_init_zero_value_node var v[10] := [0] + if (T(0) == vec_initilizer_list[0]->value()) + { + result = node_allocator_ + .allocate >( + (*vec_holder)[0], + vec_size, + vec_initilizer_list); + } + else + { + // vector_init_single_constvalue_node var v[10] := [123] + result = node_allocator_ + .allocate >( + (*vec_holder)[0], + vec_size, + vec_initilizer_list); + } } - else if ( - (se.size == vec_size) && - (scope_element::e_vector == se.type) - ) + else { - vec_holder = se.vec_node; - se.active = true; - se.depth = state_.scope_depth; - se.ref_count++; + // vector_init_single_value_node var v[10] := [123 + (x / y)] + result = node_allocator_ + .allocate >( + (*vec_holder)[0], + vec_size, + vec_initilizer_list); } } - - if (0 == vec_holder) + else if ( + (vec_initilizer_list.size() == 2) && + range_value_initialiser + ) { - scope_element nse; - nse.name = vec_name; - nse.active = true; - nse.ref_count = 1; - nse.type = scope_element::e_vector; - nse.depth = state_.scope_depth; - nse.size = vec_size; - nse.data = new T[vec_size]; - nse.vec_node = new typename scope_element::vector_holder_t(reinterpret_cast(nse.data),nse.size); + bool base_const = details::is_constant_node(vec_initilizer_list[0]); + bool inc_const = details::is_constant_node(vec_initilizer_list[1]); - if (!sem_.add_element(nse)) + if (base_const && inc_const) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM", - exprtk_error_location)); - - sem_.free_element(nse); - - return error_node(); + // vector_init_single_value_node var v[10] := [1 : 3.5] + result = node_allocator_ + .allocate >( + (*vec_holder)[0], + vec_size, + vec_initilizer_list); + } + else if (base_const && !inc_const) + { + // vector_init_single_value_node var v[10] := [1 : x + y] + result = node_allocator_ + .allocate >( + (*vec_holder)[0], + vec_size, + vec_initilizer_list); + } + else if (!base_const && inc_const) + { + // vector_init_single_value_node var v[10] := [x + y : 3] + result = node_allocator_ + .allocate >( + (*vec_holder)[0], + vec_size, + vec_initilizer_list); + } + else if (!base_const && !inc_const) + { + // vector_init_single_value_node var v[10] := [x + y : z / w] + result = node_allocator_ + .allocate >( + (*vec_holder)[0], + vec_size, + vec_initilizer_list); } - - vec_holder = nse.vec_node; - - exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n", - nse.name.c_str(), - static_cast(nse.size))); } - - state_.activate_side_effect("parse_define_vector_statement()"); - - lodge_symbol(vec_name, e_st_local_vector); - - expression_node_ptr result = error_node(); - - if (null_initialisation) + else if (null_initialisation) result = expression_generator_(T(0.0)); else if (vec_to_vec_initialiser) { @@ -26256,16 +29571,31 @@ namespace exprtk vec_initilizer_list[0]); } else + { result = node_allocator_ - .allocate >( + .allocate >( (*vec_holder)[0], vec_size, vec_initilizer_list, single_value_initialiser); + } - svd.delete_ptr = (0 == result); + svd.delete_ptr = false; - return result; + if (result && result->valid()) + { + return result; + } + + details::free_node(node_allocator_, result); + + set_error(make_error( + parser_error::e_synthesis, + current_token(), + "ERR173 - Failed to generate initialisation node for vector: " + vec_name, + exprtk_error_location)); + + return error_node(); } #ifndef exprtk_disable_string_capabilities @@ -26279,13 +29609,13 @@ namespace exprtk { if (se.active) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR163 - Illegal redefinition of local variable: '" + str_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR174 - Illegal redefinition of local variable: '" + str_name + "'", + exprtk_error_location)); - free_node(node_allocator_,initialisation_expression); + free_node(node_allocator_, initialisation_expression); return error_node(); } @@ -26311,13 +29641,13 @@ namespace exprtk if (!sem_.add_element(nse)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR164 - Failed to add new local string variable '" + str_name + "' to SEM", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR175 - Failed to add new local string variable '" + str_name + "' to SEM", + exprtk_error_location)); - free_node(node_allocator_,initialisation_expression); + free_node(node_allocator_, initialisation_expression); sem_.free_element(nse); @@ -26326,7 +29656,7 @@ namespace exprtk str_node = nse.str_node; - exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n",nse.name.c_str())); + exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n", nse.name.c_str())); } lodge_symbol(str_name, e_st_local_string); @@ -26357,11 +29687,11 @@ namespace exprtk { if (settings_.vardef_disabled()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR165 - Illegal variable definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR176 - Illegal variable definition", + exprtk_error_location)); return error_node(); } @@ -26378,41 +29708,41 @@ namespace exprtk if (!token_is(token_t::e_symbol)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR166 - Expected a symbol for variable definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR177 - Expected a symbol for variable definition", + exprtk_error_location)); return error_node(); } else if (details::is_reserved_symbol(var_name)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR167 - Illegal redefinition of reserved keyword: '" + var_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR178 - Illegal redefinition of reserved keyword: '" + var_name + "'", + exprtk_error_location)); return error_node(); } else if (symtab_store_.symbol_exists(var_name)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR168 - Illegal redefinition of variable '" + var_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR179 - Illegal redefinition of variable '" + var_name + "'", + exprtk_error_location)); return error_node(); } else if (local_variable_is_shadowed(var_name)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR169 - Illegal redefinition of local variable: '" + var_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR180 - Illegal redefinition of local variable: '" + var_name + "'", + exprtk_error_location)); return error_node(); } @@ -26428,11 +29758,11 @@ namespace exprtk { if (0 == (initialisation_expression = parse_expression())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR170 - Failed to parse initialisation expression", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR181 - Failed to parse initialisation expression for variable '" + var_name + "'", + exprtk_error_location)); return error_node(); } @@ -26446,13 +29776,13 @@ namespace exprtk { if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR171 - Expected ';' after variable definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR182 - Expected ';' after variable '" + var_name + "' definition", + exprtk_error_location)); - free_node(node_allocator_,initialisation_expression); + free_node(node_allocator_, initialisation_expression); return error_node(); } @@ -26474,11 +29804,11 @@ namespace exprtk { if (se.active) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR172 - Illegal redefinition of local variable: '" + var_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR183 - Illegal redefinition of local variable: '" + var_name + "'", + exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -26506,11 +29836,11 @@ namespace exprtk if (!sem_.add_element(nse)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR173 - Failed to add new local variable '" + var_name + "' to SEM", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR184 - Failed to add new local variable '" + var_name + "' to SEM", + exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -26521,7 +29851,7 @@ namespace exprtk var_node = nse.var_node; - exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n",nse.name.c_str())); + exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n", nse.name.c_str())); } state_.activate_side_effect("parse_define_var_statement()"); @@ -26536,6 +29866,174 @@ namespace exprtk return expression_generator_(details::e_assign,branch); } + inline expression_node_ptr parse_define_constvar_statement() + { + if (settings_.vardef_disabled()) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR185 - Illegal const variable definition", + exprtk_error_location)); + + return error_node(); + } + else if (!token_is("const")) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR186 - Expected 'const' keyword for const-variable definition", + exprtk_error_location)); + + return error_node(); + } + else if (!token_is("var")) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR187 - Expected 'var' keyword for const-variable definition", + exprtk_error_location)); + + return error_node(); + } + + const std::string var_name = current_token().value; + + expression_node_ptr initialisation_expression = error_node(); + + if (!token_is(token_t::e_symbol)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR188 - Expected a symbol for const-variable definition", + exprtk_error_location)); + + return error_node(); + } + else if (details::is_reserved_symbol(var_name)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR189 - Illegal redefinition of reserved keyword: '" + var_name + "'", + exprtk_error_location)); + + return error_node(); + } + else if (symtab_store_.symbol_exists(var_name)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR190 - Illegal redefinition of variable '" + var_name + "'", + exprtk_error_location)); + + return error_node(); + } + else if (local_variable_is_shadowed(var_name)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR191 - Illegal redefinition of local variable: '" + var_name + "'", + exprtk_error_location)); + + return error_node(); + } + else if (token_is(token_t::e_assign)) + { + if (0 == (initialisation_expression = parse_expression())) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR192 - Failed to parse initialisation expression for const-variable: '" + var_name + "'", + exprtk_error_location)); + + return error_node(); + } + else if (!details::is_literal_node(initialisation_expression)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR193 - initialisation expression for const-variable: '" + var_name + "' must be a constant/literal", + exprtk_error_location)); + + free_node(node_allocator_, initialisation_expression); + + return error_node(); + } + } + + const T init_value = initialisation_expression->value(); + + free_node(node_allocator_, initialisation_expression); + + expression_node_ptr var_node = reinterpret_cast(0); + + scope_element& se = sem_.get_element(var_name); + + if (se.name == var_name) + { + if (se.active) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR194 - Illegal redefinition of local variable: '" + var_name + "'", + exprtk_error_location)); + + return error_node(); + } + else if (scope_element::e_literal == se.type) + { + var_node = se.var_node; + se.active = true; + se.depth = state_.scope_depth; + se.ref_count++; + } + } + + if (0 == var_node) + { + scope_element nse; + nse.name = var_name; + nse.active = true; + nse.ref_count = 1; + nse.type = scope_element::e_literal; + nse.depth = state_.scope_depth; + nse.data = 0; + nse.var_node = node_allocator_.allocate(init_value); + + if (!sem_.add_element(nse)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR195 - Failed to add new local const-variable '" + var_name + "' to SEM", + exprtk_error_location)); + + sem_.free_element(nse); + + return error_node(); + } + + var_node = nse.var_node; + + exprtk_debug(("parse_define_constvar_statement() - INFO - Added new local const-variable: %s\n", nse.name.c_str())); + } + + state_.activate_side_effect("parse_define_constvar_statement()"); + + lodge_symbol(var_name, e_st_local_variable); + + return expression_generator_(var_node->value()); + } + inline expression_node_ptr parse_uninitialised_var_statement(const std::string& var_name) { if ( @@ -26543,21 +30041,21 @@ namespace exprtk !token_is(token_t::e_rcrlbracket) ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR174 - Expected a '{}' for uninitialised var definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR196 - Expected a '{}' for uninitialised var definition", + exprtk_error_location)); return error_node(); } else if (!token_is(token_t::e_eof,prsrhlpr_t::e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR175 - Expected ';' after uninitialised variable definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR197 - Expected ';' after uninitialised variable definition", + exprtk_error_location)); return error_node(); } @@ -26570,11 +30068,11 @@ namespace exprtk { if (se.active) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR176 - Illegal redefinition of local variable: '" + var_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR198 - Illegal redefinition of local variable: '" + var_name + "'", + exprtk_error_location)); return error_node(); } @@ -26600,11 +30098,11 @@ namespace exprtk if (!sem_.add_element(nse)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR177 - Failed to add new local variable '" + var_name + "' to SEM", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR199 - Failed to add new local variable '" + var_name + "' to SEM", + exprtk_error_location)); sem_.free_element(nse); @@ -26633,11 +30131,11 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR178 - Expected '(' at start of swap statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR200 - Expected '(' at start of swap statement", + exprtk_error_location)); return error_node(); } @@ -26652,11 +30150,11 @@ namespace exprtk if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR179 - Expected a symbol for variable or vector element definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR201 - Expected a symbol for variable or vector element definition", + exprtk_error_location)); return error_node(); } @@ -26664,11 +30162,11 @@ namespace exprtk { if (0 == (variable0 = parse_vector())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR180 - First parameter to swap is an invalid vector element: '" + var0_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR202 - First parameter to swap is an invalid vector element: '" + var0_name + "'", + exprtk_error_location)); return error_node(); } @@ -26697,11 +30195,11 @@ namespace exprtk if (0 == variable0) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR181 - First parameter to swap is an invalid variable: '" + var0_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR203 - First parameter to swap is an invalid variable: '" + var0_name + "'", + exprtk_error_location)); return error_node(); } @@ -26711,15 +30209,15 @@ namespace exprtk if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR182 - Expected ',' between parameters to swap", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR204 - Expected ',' between parameters to swap", + exprtk_error_location)); if (variable0_generated) { - free_node(node_allocator_,variable0); + free_node(node_allocator_, variable0); } return error_node(); @@ -26729,15 +30227,15 @@ namespace exprtk if (!token_is(token_t::e_symbol,prsrhlpr_t::e_hold)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR183 - Expected a symbol for variable or vector element definition", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR205 - Expected a symbol for variable or vector element definition", + exprtk_error_location)); if (variable0_generated) { - free_node(node_allocator_,variable0); + free_node(node_allocator_, variable0); } return error_node(); @@ -26746,15 +30244,15 @@ namespace exprtk { if (0 == (variable1 = parse_vector())) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR184 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR206 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", + exprtk_error_location)); if (variable0_generated) { - free_node(node_allocator_,variable0); + free_node(node_allocator_, variable0); } return error_node(); @@ -26784,15 +30282,15 @@ namespace exprtk if (0 == variable1) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR185 - Second parameter to swap is an invalid variable: '" + var1_name + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR207 - Second parameter to swap is an invalid variable: '" + var1_name + "'", + exprtk_error_location)); if (variable0_generated) { - free_node(node_allocator_,variable0); + free_node(node_allocator_, variable0); } return error_node(); @@ -26803,20 +30301,20 @@ namespace exprtk if (!token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR186 - Expected ')' at end of swap statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR208 - Expected ')' at end of swap statement", + exprtk_error_location)); if (variable0_generated) { - free_node(node_allocator_,variable0); + free_node(node_allocator_, variable0); } if (variable1_generated) { - free_node(node_allocator_,variable1); + free_node(node_allocator_, variable1); } return error_node(); @@ -26838,12 +30336,12 @@ namespace exprtk if (variable0_generated) { - free_node(node_allocator_,variable0); + free_node(node_allocator_, variable0); } if (variable1_generated) { - free_node(node_allocator_,variable1); + free_node(node_allocator_, variable1); } } else @@ -26860,11 +30358,11 @@ namespace exprtk { if (state_.parsing_return_stmt) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR187 - Return call within a return call is not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR209 - Return call within a return call is not allowed", + exprtk_error_location)); return error_node(); } @@ -26884,11 +30382,11 @@ namespace exprtk if (!token_is(token_t::e_lsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR188 - Expected '[' at start of return statement", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR210 - Expected '[' at start of return statement", + exprtk_error_location)); return error_node(); } @@ -26907,11 +30405,11 @@ namespace exprtk break; else if (!token_is(token_t::e_comma)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR189 - Expected ',' between values during call to return", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR211 - Expected ',' between values during call to return", + exprtk_error_location)); return error_node(); } @@ -26919,11 +30417,11 @@ namespace exprtk } else if (settings_.zero_return_disabled()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR190 - Zero parameter return statement not allowed", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR212 - Zero parameter return statement not allowed", + exprtk_error_location)); return error_node(); } @@ -26934,11 +30432,11 @@ namespace exprtk { if (!arg_list.empty()) { - set_error( - make_error(parser_error::e_syntax, - prev_token, - "ERR191 - Invalid ']' found during return call", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + prev_token, + "ERR213 - Invalid ']' found during return call", + exprtk_error_location)); return error_node(); } @@ -26977,6 +30475,194 @@ namespace exprtk } #endif + inline expression_node_ptr parse_assert_statement() + { + assert(details::imatch(current_token().value, "assert")); + + if (state_.parsing_assert_stmt) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR214 - Assert statement within an assert statement is not allowed", + exprtk_error_location)); + + return error_node(); + } + + scoped_bool_negator sbn(state_.parsing_assert_stmt); + + next_token(); + + std::vector assert_arg_list(3, error_node()); + scoped_vec_delete sdd((*this), assert_arg_list); + + expression_node_ptr& assert_condition = assert_arg_list[0]; + expression_node_ptr& assert_message = assert_arg_list[1]; + expression_node_ptr& assert_id = assert_arg_list[2]; + + if (!token_is(token_t::e_lbracket)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR215 - Expected '(' at start of assert statement", + exprtk_error_location)); + + return error_node(); + } + + const token_t start_token = current_token(); + + // Parse the assert condition + if (0 == (assert_condition = parse_expression())) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR216 - Failed to parse condition for assert statement", + exprtk_error_location)); + + return error_node(); + } + + const token_t end_token = current_token(); + + if (!token_is(token_t::e_rbracket)) + { + if (!token_is(token_t::e_comma)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR217 - Expected ',' between condition and message for assert statement", + exprtk_error_location)); + + return error_node(); + } + // Parse the assert message + else if ( + (0 == (assert_message = parse_expression())) || + !details::is_generally_string_node(assert_message) + ) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR218 - " + + (assert_message ? + std::string("Expected string for assert message") : + std::string("Failed to parse message for assert statement")), + exprtk_error_location)); + + return error_node(); + } + else if (!token_is(token_t::e_rbracket)) + { + if (!token_is(token_t::e_comma)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR219 - Expected ',' between message and ID for assert statement", + exprtk_error_location)); + + return error_node(); + } + // Parse assert ID + else if ( + (0 == (assert_id = parse_expression())) || + !details::is_const_string_node(assert_id) + ) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR220 - " + + (assert_id ? + std::string("Expected literal string for assert ID") : + std::string("Failed to parse string for assert ID")), + exprtk_error_location)); + + return error_node(); + } + else if (!token_is(token_t::e_rbracket)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR221 - Expected ')' at start of assert statement", + exprtk_error_location)); + + return error_node(); + } + } + } + + exprtk::assert_check::assert_context context; + context.condition = lexer().substr(start_token.position, end_token.position); + context.offet = start_token.position; + + if (0 == assert_check_) + { + exprtk_debug(("parse_assert_statement() - assert functionality is disabled. assert condition: %s\n", + context.condition.c_str())); + + return new details::null_node(); + } + + #ifndef exprtk_disable_string_capabilities + if (assert_message && details::is_const_string_node(assert_message)) + { + context.message = dynamic_cast*>(assert_message)->str(); + } + + if (assert_id && details::is_const_string_node(assert_id)) + { + context.id = dynamic_cast*>(assert_id)->str(); + + if (assert_ids_.end() != assert_ids_.find(context.id)) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR222 - Duplicate assert ID: " + context.id, + exprtk_error_location)); + + return error_node(); + } + + assert_ids_.insert(context.id); + free_node(node_allocator_, assert_id); + } + #endif + + expression_node_ptr result_node = + expression_generator_.assert_call( + assert_condition, + assert_message, + context); + + exprtk_debug(("parse_assert_statement() - assert condition: [%s]\n", context.condition.c_str() )); + exprtk_debug(("parse_assert_statement() - assert message: [%s]\n", context.message .c_str() )); + exprtk_debug(("parse_assert_statement() - assert id: [%s]\n", context.id .c_str() )); + exprtk_debug(("parse_assert_statement() - assert offset: [%d]\n", static_cast(context.offet))); + + if (0 == result_node) + { + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR223 - Failed to synthesize assert", + exprtk_error_location)); + + return error_node(); + } + + sdd.delete_ptr = false; + return result_node; + } + inline bool post_variable_process(const std::string& symbol) { if ( @@ -26987,11 +30673,11 @@ namespace exprtk { if (!settings_.commutative_check_enabled()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR192 - Invalid sequence of variable '" + symbol + "' and bracket", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR224 - Invalid sequence of variable '" + symbol + "' and bracket", + exprtk_error_location)); return false; } @@ -27009,23 +30695,26 @@ namespace exprtk if (details::is_generally_string_node(branch)) return true; + if (details::is_ivector_node(branch)) + return true; + const lexer::parser_helper::token_advance_mode hold = prsrhlpr_t::e_hold; switch (token) { - case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket ,hold) || - token_is(token_t::e_lcrlbracket,hold) || - token_is(token_t::e_lsqrbracket,hold) ; + case token_t::e_lcrlbracket : implied_mul = token_is(token_t::e_lbracket , hold) || + token_is(token_t::e_lcrlbracket, hold) || + token_is(token_t::e_lsqrbracket, hold) ; break; - case token_t::e_lbracket : implied_mul = token_is(token_t::e_lbracket ,hold) || - token_is(token_t::e_lcrlbracket,hold) || - token_is(token_t::e_lsqrbracket,hold) ; + case token_t::e_lbracket : implied_mul = token_is(token_t::e_lbracket , hold) || + token_is(token_t::e_lcrlbracket, hold) || + token_is(token_t::e_lsqrbracket, hold) ; break; - case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket ,hold) || - token_is(token_t::e_lcrlbracket,hold) || - token_is(token_t::e_lsqrbracket,hold) ; + case token_t::e_lsqrbracket : implied_mul = token_is(token_t::e_lbracket , hold) || + token_is(token_t::e_lcrlbracket, hold) || + token_is(token_t::e_lsqrbracket, hold) ; break; default : return true; @@ -27035,11 +30724,11 @@ namespace exprtk { if (!settings_.commutative_check_enabled()) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR193 - Invalid sequence of brackets", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR225 - Invalid sequence of brackets", + exprtk_error_location)); return false; } @@ -27122,7 +30811,10 @@ namespace exprtk if (se.active && details::imatch(se.name, symbol)) { - if (scope_element::e_variable == se.type) + if ( + (scope_element::e_variable == se.type) || + (scope_element::e_literal == se.type) + ) { se.active = true; lodge_symbol(symbol, e_st_local_variable); @@ -27132,7 +30824,9 @@ namespace exprtk next_token(); - return se.var_node; + return (scope_element::e_variable == se.type) ? + se.var_node : + expression_generator_(se.var_node->value()); } else if (scope_element::e_vector == se.type) { @@ -27170,11 +30864,11 @@ namespace exprtk return func_node; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR194 - Failed to generate node for function: '" + symbol + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR226 - Failed to generate node for function: '" + symbol + "'", + exprtk_error_location)); return error_node(); } @@ -27196,11 +30890,11 @@ namespace exprtk return vararg_func_node; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR195 - Failed to generate node for vararg function: '" + symbol + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR227 - Failed to generate node for vararg function: '" + symbol + "'", + exprtk_error_location)); return error_node(); } @@ -27222,11 +30916,11 @@ namespace exprtk return genericfunc_node; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR196 - Failed to generate node for generic function: '" + symbol + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR228 - Failed to generate node for generic function: '" + symbol + "'", + exprtk_error_location)); return error_node(); } @@ -27249,11 +30943,11 @@ namespace exprtk return stringfunc_node; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR197 - Failed to generate node for string function: '" + symbol + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR229 - Failed to generate node for string function: '" + symbol + "'", + exprtk_error_location)); return error_node(); } @@ -27275,11 +30969,11 @@ namespace exprtk return overloadfunc_node; else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR198 - Failed to generate node for overload function: '" + symbol + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR230 - Failed to generate node for overload function: '" + symbol + "'", + exprtk_error_location)); return error_node(); } @@ -27301,11 +30995,11 @@ namespace exprtk !details::is_base_function(symbol) ) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR199 - Invalid use of reserved symbol '" + symbol + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR231 - Invalid use of reserved symbol '" + symbol + "'", + exprtk_error_location)); return error_node(); } @@ -27332,11 +31026,13 @@ namespace exprtk switch (usr_symbol_type) { - case unknown_symbol_resolver::e_usr_variable_type : create_result = symtab.create_variable(symbol, default_value); - break; + case unknown_symbol_resolver::e_usr_variable_type : + create_result = symtab.create_variable(symbol, default_value); + break; - case unknown_symbol_resolver::e_usr_constant_type : create_result = symtab.add_constant(symbol, default_value); - break; + case unknown_symbol_resolver::e_usr_constant_type : + create_result = symtab.add_constant(symbol, default_value); + break; default : create_result = false; } @@ -27364,12 +31060,12 @@ namespace exprtk } } - set_error( - make_error(parser_error::e_symtab, - current_token(), - "ERR200 - Failed to create variable: '" + symbol + "'" + - (error_message.empty() ? "" : " - " + error_message), - exprtk_error_location)); + set_error(make_error( + parser_error::e_symtab, + current_token(), + "ERR232 - Failed to create variable: '" + symbol + "'" + + (error_message.empty() ? "" : " - " + error_message), + exprtk_error_location)); } else if (unknown_symbol_resolver::e_usrmode_extended == unknown_symbol_resolver_->mode) @@ -27384,27 +31080,51 @@ namespace exprtk } } - set_error( - make_error(parser_error::e_symtab, - current_token(), - "ERR201 - Failed to resolve symbol: '" + symbol + "'" + - (error_message.empty() ? "" : " - " + error_message), - exprtk_error_location)); + set_error(make_error( + parser_error::e_symtab, + current_token(), + "ERR233 - Failed to resolve symbol: '" + symbol + "'" + + (error_message.empty() ? "" : " - " + error_message), + exprtk_error_location)); } return error_node(); } } - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR202 - Undefined symbol: '" + symbol + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR234 - Undefined symbol: '" + symbol + "'", + exprtk_error_location)); return error_node(); } + inline expression_node_ptr check_block_statement_closure(expression_node_ptr expression) + { + if ( + expression && + ( + (current_token().type == token_t::e_symbol) || + (current_token().type == token_t::e_number) + ) + ) + { + free_node(node_allocator_, expression); + + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR235 - Invalid syntax '" + current_token().value + "' possible missing operator or context", + exprtk_error_location)); + + return error_node(); + } + + return expression; + } + inline expression_node_ptr parse_symbol() { static const std::string symbol_if = "if" ; @@ -27416,9 +31136,11 @@ namespace exprtk static const std::string symbol_break = "break" ; static const std::string symbol_continue = "continue"; static const std::string symbol_var = "var" ; + static const std::string symbol_const = "const" ; static const std::string symbol_swap = "swap" ; static const std::string symbol_return = "return" ; static const std::string symbol_not = "not" ; + static const std::string symbol_assert = "assert" ; const std::string symbol = current_token().value; @@ -27446,28 +31168,28 @@ namespace exprtk settings_.control_struct_enabled(symbol) ) { - return parse_while_loop(); + return check_block_statement_closure(parse_while_loop()); } else if ( details::imatch(symbol, symbol_repeat) && settings_.control_struct_enabled(symbol) ) { - return parse_repeat_until_loop(); + return check_block_statement_closure(parse_repeat_until_loop()); } else if ( details::imatch(symbol, symbol_for) && settings_.control_struct_enabled(symbol) ) { - return parse_for_loop(); + return check_block_statement_closure(parse_for_loop()); } else if ( details::imatch(symbol, symbol_switch) && settings_.control_struct_enabled(symbol) ) { - return parse_switch_statement(); + return check_block_statement_closure(parse_switch_statement()); } else if (details::is_valid_sf_symbol(symbol)) { @@ -27491,6 +31213,10 @@ namespace exprtk { return parse_define_var_statement(); } + else if (details::imatch(symbol, symbol_const)) + { + return parse_define_constvar_statement(); + } else if (details::imatch(symbol, symbol_swap)) { return parse_swap_statement(); @@ -27501,20 +31227,25 @@ namespace exprtk settings_.control_struct_enabled(symbol) ) { - return parse_return_statement(); + return check_block_statement_closure(parse_return_statement()); } #endif + else if (details::imatch(symbol, symbol_assert)) + { + return parse_assert_statement(); + } else if (symtab_store_.valid() || !sem_.empty()) { return parse_symtab_symbol(); } else { - set_error( - make_error(parser_error::e_symtab, - current_token(), - "ERR203 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol, - exprtk_error_location)); + set_error(make_error( + parser_error::e_symtab, + current_token(), + "ERR236 - Unknown variable or function encountered. Symbol table(s) " + "is either invalid or does not contain symbol: '" + symbol + "'", + exprtk_error_location)); return error_node(); } @@ -27541,11 +31272,11 @@ namespace exprtk if (0 == literal_exp) { - set_error( - make_error(parser_error::e_numeric, - current_token(), - "ERR204 - Failed generate node for scalar: '" + current_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_numeric, + current_token(), + "ERR237 - Failed generate node for scalar: '" + current_token().value + "'", + exprtk_error_location)); return error_node(); } @@ -27555,11 +31286,11 @@ namespace exprtk } else { - set_error( - make_error(parser_error::e_numeric, - current_token(), - "ERR205 - Failed to convert '" + current_token().value + "' to a number", - exprtk_error_location)); + set_error(make_error( + parser_error::e_numeric, + current_token(), + "ERR238 - Failed to convert '" + current_token().value + "' to a number", + exprtk_error_location)); return error_node(); } @@ -27579,25 +31310,32 @@ namespace exprtk next_token(); if (0 == (branch = parse_expression())) + { return error_node(); - else if (!token_is(token_t::e_rbracket)) + } + + token_is(token_t::e_eof); + + if (!token_is(token_t::e_rbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR206 - Expected ')' instead of: '" + current_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR239 - Expected ')' instead of: '" + current_token().value + "'", + exprtk_error_location)); - details::free_node(node_allocator_,branch); + details::free_node(node_allocator_, branch); return error_node(); } else if (!post_bracket_process(token_t::e_lbracket,branch)) { - details::free_node(node_allocator_,branch); + details::free_node(node_allocator_, branch); return error_node(); } + + parse_pending_vector_index_operator(branch); } else if (token_t::e_lsqrbracket == current_token().type) { @@ -27607,19 +31345,19 @@ namespace exprtk return error_node(); else if (!token_is(token_t::e_rsqrbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR207 - Expected ']' instead of: '" + current_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR240 - Expected ']' instead of: '" + current_token().value + "'", + exprtk_error_location)); - details::free_node(node_allocator_,branch); + details::free_node(node_allocator_, branch); return error_node(); } else if (!post_bracket_process(token_t::e_lsqrbracket,branch)) { - details::free_node(node_allocator_,branch); + details::free_node(node_allocator_, branch); return error_node(); } @@ -27632,19 +31370,19 @@ namespace exprtk return error_node(); else if (!token_is(token_t::e_rcrlbracket)) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR208 - Expected '}' instead of: '" + current_token().value + "'", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR241 - Expected '}' instead of: '" + current_token().value + "'", + exprtk_error_location)); - details::free_node(node_allocator_,branch); + details::free_node(node_allocator_, branch); return error_node(); } else if (!post_bracket_process(token_t::e_lcrlbracket,branch)) { - details::free_node(node_allocator_,branch); + details::free_node(node_allocator_, branch); return error_node(); } @@ -27666,7 +31404,7 @@ namespace exprtk if (0 == result) { - details::free_node(node_allocator_,branch); + details::free_node(node_allocator_, branch); return error_node(); } @@ -27681,21 +31419,21 @@ namespace exprtk } else if (token_t::e_eof == current_token().type) { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR209 - Premature end of expression[1]", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR242 - Premature end of expression[1]", + exprtk_error_location)); return error_node(); } else { - set_error( - make_error(parser_error::e_syntax, - current_token(), - "ERR210 - Premature end of expression[2]", - exprtk_error_location)); + set_error(make_error( + parser_error::e_syntax, + current_token(), + "ERR243 - Premature end of expression[2]", + exprtk_error_location)); return error_node(); } @@ -27796,6 +31534,8 @@ namespace exprtk register_synthezier(synthesize_covocov_expression4) register_synthezier(synthesize_vocovoc_expression4) register_synthezier(synthesize_covovoc_expression4) + + #undef register_synthezier #endif } @@ -27848,7 +31588,7 @@ namespace exprtk { typename binary_op_map_t::iterator bop_itr = binary_op_map_->find(operation); - if ((*binary_op_map_).end() == bop_itr) + if (binary_op_map_->end() == bop_itr) return false; bop = bop_itr->second; @@ -28260,13 +32000,20 @@ namespace exprtk if (details::is_string_node(branch[0])) return !b1_is_genstring; + else if (details::is_literal_node(branch[0])) + return true; else return ( - !details::is_variable_node (branch[0]) && - !details::is_vector_elem_node (branch[0]) && - !details::is_rebasevector_elem_node (branch[0]) && - !details::is_rebasevector_celem_node(branch[0]) && - !details::is_vector_node (branch[0]) + !details::is_variable_node (branch[0]) && + !details::is_vector_elem_node (branch[0]) && + !details::is_vector_celem_node (branch[0]) && + !details::is_vector_elem_rtc_node (branch[0]) && + !details::is_vector_celem_rtc_node (branch[0]) && + !details::is_rebasevector_elem_node (branch[0]) && + !details::is_rebasevector_celem_node (branch[0]) && + !details::is_rebasevector_elem_rtc_node (branch[0]) && + !details::is_rebasevector_celem_rtc_node(branch[0]) && + !details::is_vector_node (branch[0]) ) || b1_is_genstring; } @@ -28421,18 +32168,42 @@ namespace exprtk { if ((0 == branch[0]) || (0 == branch[1])) { + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR244 - Invalid branches received for operator '" + details::to_str(operation) + "'", + exprtk_error_location)); + return error_node(); } else if (is_invalid_string_op(operation,branch)) { + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR245 - Invalid branch pair for string operator '" + details::to_str(operation) + "'", + exprtk_error_location)); + return error_node(); } else if (is_invalid_assignment_op(operation,branch)) { + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR246 - Invalid branch pair for assignment operator '" + details::to_str(operation) + "'", + exprtk_error_location)); + return error_node(); } else if (is_invalid_break_continue_op(branch)) { + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR247 - Invalid branch pair for break/continue operator '" + details::to_str(operation) + "'", + exprtk_error_location)); + return error_node(); } else if (details::e_assign == operation) @@ -28551,10 +32322,22 @@ namespace exprtk { details::free_all_nodes(*node_allocator_,branch); + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR248 - Invalid branches operator '" + details::to_str(operation) + "'", + exprtk_error_location)); + return error_node(); } else if (is_invalid_string_op(operation, branch)) { + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR249 - Invalid branches for string operator '" + details::to_str(operation) + "'", + exprtk_error_location)); + return error_node(); } else if (is_string_operation(operation, branch)) @@ -28601,6 +32384,16 @@ namespace exprtk details::free_node(*node_allocator_, consequent ); details::free_node(*node_allocator_, alternative); + const std::string invalid_branches = + ((0 == condition ) ? std::string("condition ") : "") + + ((0 == consequent) ? std::string("consequent") : "") ; + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + parser_->current_state().token, + "ERR250 - Invalid " + invalid_branches + " for conditional statement", + exprtk_error_location)); + return error_node(); } // Can the condition be immediately evaluated? if so optimise. @@ -28626,14 +32419,34 @@ namespace exprtk return node_allocator_->allocate >(); } } - else if ((0 != consequent) && (0 != alternative)) + + expression_node_ptr result = error_node(); + std::string node_name = "Unknown!"; + + if ((0 != consequent) && (0 != alternative)) { - return node_allocator_-> - allocate(condition, consequent, alternative); + result = node_allocator_->allocate(condition, consequent, alternative); + node_name = "conditional_node_t"; } else - return node_allocator_-> - allocate(condition, consequent); + { + result = node_allocator_->allocate(condition, consequent); + node_name = "cons_conditional_node_t"; + } + + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + token_t(), + "ERR251 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } #ifndef exprtk_disable_string_capabilities @@ -28647,6 +32460,16 @@ namespace exprtk details::free_node(*node_allocator_, consequent ); details::free_node(*node_allocator_, alternative); + const std::string invalid_branches = + ((0 == condition ) ? std::string("condition ") : "") + + ((0 == consequent) ? std::string("consequent") : "") ; + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + parser_->current_state().token, + "ERR252 - Invalid " + invalid_branches + " for string conditional statement", + exprtk_error_location)); + return error_node(); } // Can the condition be immediately evaluated? if so optimise. @@ -28674,10 +32497,25 @@ namespace exprtk } } else if ((0 != consequent) && (0 != alternative)) - return node_allocator_-> - allocate(condition, consequent, alternative); - else - return error_node(); + { + expression_node_ptr result = + node_allocator_->allocate(condition, consequent, alternative); + + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + token_t(), + "ERR253 - Failed to synthesize node: conditional_string_node_t", + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + } + + return error_node(); } #else inline expression_node_ptr conditional_string(expression_node_ptr, @@ -28698,6 +32536,16 @@ namespace exprtk details::free_node(*node_allocator_, consequent ); details::free_node(*node_allocator_, alternative); + const std::string invalid_branches = + ((0 == condition ) ? std::string("condition ") : "") + + ((0 == consequent) ? std::string("consequent") : "") ; + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + parser_->current_state().token, + "ERR254 - Invalid " + invalid_branches + " for vector conditional statement", + exprtk_error_location)); + return error_node(); } // Can the condition be immediately evaluated? if so optimise. @@ -28746,16 +32594,34 @@ namespace exprtk return loop_runtime_check_ptr(0); } + inline vector_access_runtime_check_ptr get_vector_access_runtime_check() const + { + return parser_->vector_access_runtime_check_; + } + inline expression_node_ptr while_loop(expression_node_ptr& condition, expression_node_ptr& branch, const bool break_continue_present = false) const { - if (!break_continue_present && details::is_constant_node(condition)) + if ( + !break_continue_present && + !parser_->state_.return_stmt_present && + details::is_constant_node(condition) + ) { expression_node_ptr result = error_node(); if (details::is_true(condition)) + { // Infinite loops are not allowed. + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + parser_->current_state().token, + "ERR255 - Infinite loop condition without 'break' or 'return' not allowed in while-loops", + exprtk_error_location)); + result = error_node(); + } else result = node_allocator_->allocate >(); @@ -28857,13 +32723,26 @@ namespace exprtk expression_node_ptr& loop_body, bool break_continue_present = false) const { - if (!break_continue_present && details::is_constant_node(condition)) + if ( + !break_continue_present && + !parser_->state_.return_stmt_present && + details::is_constant_node(condition) + ) { expression_node_ptr result = error_node(); if (details::is_true(condition)) + { // Infinite loops are not allowed. + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + parser_->current_state().token, + "ERR256 - Infinite loop condition without 'break' or 'return' not allowed in for-loop", + exprtk_error_location)); + result = error_node(); + } else result = node_allocator_->allocate >(); @@ -28890,19 +32769,19 @@ namespace exprtk if (rtc) return node_allocator_->allocate ( - initialiser, - condition, - incrementor, - loop_body, - rtc + initialiser, + condition, + incrementor, + loop_body, + rtc ); else return node_allocator_->allocate ( - initialiser, - condition, - incrementor, - loop_body + initialiser, + condition, + incrementor, + loop_body ); } #ifndef exprtk_disable_break_continue @@ -28911,19 +32790,19 @@ namespace exprtk if (rtc) return node_allocator_->allocate ( - initialiser, - condition, - incrementor, - loop_body, - rtc + initialiser, + condition, + incrementor, + loop_body, + rtc ); else return node_allocator_->allocate ( - initialiser, - condition, - incrementor, - loop_body + initialiser, + condition, + incrementor, + loop_body ); } #else @@ -28986,8 +32865,8 @@ namespace exprtk if (0 == result) { - T zero = T(0); - result = node_allocator_->allocate(zero); + const T zero = T(0); + result = node_allocator_->allocate(zero); } for (std::size_t i = 0; i < arg_list.size(); ++i) @@ -29161,6 +33040,28 @@ namespace exprtk return node_allocator_->allocate >(arg_list); } + inline expression_node_ptr assert_call(expression_node_ptr& assert_condition, + expression_node_ptr& assert_message, + const assert_check::assert_context& context) + { + typedef details::assert_node alloc_type; + + expression_node_ptr result = node_allocator_->allocate_rrrr + (assert_condition, assert_message, parser_->assert_check_, context); + + if (result && result->valid()) + { + parser_->state_.activate_side_effect("assert_call()"); + return result; + } + + details::free_node(*node_allocator_, result ); + details::free_node(*node_allocator_, assert_condition); + details::free_node(*node_allocator_, assert_message ); + + return error_node(); + } + #define unary_opr_switch_statements \ case_stmt(details::e_abs , details::abs_op ) \ case_stmt(details::e_acos , details::acos_op ) \ @@ -29280,6 +33181,8 @@ namespace exprtk default : return error_node(); } + assert(temp_node); + const T v = temp_node->value(); details::free_node(*node_allocator_,temp_node); @@ -29383,6 +33286,8 @@ namespace exprtk default : return error_node(); } + assert(temp_node); + const T v = temp_node->value(); details::free_node(*node_allocator_,temp_node); @@ -29503,7 +33408,8 @@ namespace exprtk template class Sequence> - inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation, Sequence& arg_list) + inline expression_node_ptr varnode_optimise_varargfunc(const details::operator_type& operation, + Sequence& arg_list) { switch (operation) { @@ -29526,7 +33432,8 @@ namespace exprtk template class Sequence> - inline expression_node_ptr vectorize_func(const details::operator_type& operation, Sequence& arg_list) + inline expression_node_ptr vectorize_func(const details::operator_type& operation, + Sequence& arg_list) { if (1 == arg_list.size()) { @@ -29551,7 +33458,8 @@ namespace exprtk template class Sequence> - inline expression_node_ptr vararg_function(const details::operator_type& operation, Sequence& arg_list) + inline expression_node_ptr vararg_function(const details::operator_type& operation, + Sequence& arg_list) { if (!all_nodes_valid(arg_list)) { @@ -29561,9 +33469,9 @@ namespace exprtk } else if (is_constant_foldable(arg_list)) return const_optimise_varargfunc(operation,arg_list); - else if ((arg_list.size() == 1) && details::is_ivector_node(arg_list[0])) + else if ((1 == arg_list.size()) && details::is_ivector_node(arg_list[0])) return vectorize_func(operation,arg_list); - else if ((arg_list.size() == 1) && special_one_parameter_vararg(operation)) + else if ((1 == arg_list.size()) && special_one_parameter_vararg(operation)) return arg_list[0]; else if (all_nodes_variables(arg_list)) return varnode_optimise_varargfunc(operation,arg_list); @@ -29571,17 +33479,32 @@ namespace exprtk #ifndef exprtk_disable_string_capabilities if (details::e_smulti == operation) { - return node_allocator_-> + expression_node_ptr result = node_allocator_-> allocate > >(arg_list); + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR257 - Failed to synthesize node: str_vararg_node", + exprtk_error_location)); + + details::free_node(*node_allocator_, result); } else #endif { + expression_node_ptr result = error_node(); + switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ allocate > >(arg_list); \ + break; \ case_stmt(details::e_sum , details::vararg_add_op ) case_stmt(details::e_prod , details::vararg_mul_op ) @@ -29594,7 +33517,22 @@ namespace exprtk #undef case_stmt default : return error_node(); } + + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR258 - Failed to synthesize node: vararg_node", + exprtk_error_location)); + + details::free_node(*node_allocator_, result); } + + return error_node(); } template @@ -29635,7 +33573,19 @@ namespace exprtk return error_node(); } - return result; + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR259 - Failed to synthesize node: function_N_node_t", + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } } @@ -29672,7 +33622,19 @@ namespace exprtk parser_->state_.activate_side_effect("vararg_function_call()"); - return result; + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR260 - Failed to synthesize node: vararg_function_node", + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } inline expression_node_ptr generic_function_call(igeneric_function_t* gf, @@ -29691,14 +33653,23 @@ namespace exprtk const std::size_t no_psi = std::numeric_limits::max(); expression_node_ptr result = error_node(); + std::string node_name = "Unknown"; if (no_psi == param_seq_index) + { result = node_allocator_->allocate(arg_list,gf); + node_name = "generic_function_node"; + } else + { result = node_allocator_->allocate(gf, param_seq_index, arg_list); + node_name = "multimode_genfunction_node"; + } alloc_type1* genfunc_node_ptr = static_cast(result); + assert(genfunc_node_ptr); + if ( !arg_list.empty() && !gf->has_side_effects() && @@ -29716,9 +33687,20 @@ namespace exprtk } else if (genfunc_node_ptr->init_branches()) { - parser_->state_.activate_side_effect("generic_function_call()"); + if (result && result->valid()) + { + parser_->state_.activate_side_effect("generic_function_call()"); + return result; + } - return result; + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR261 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } else { @@ -29746,14 +33728,23 @@ namespace exprtk const std::size_t no_psi = std::numeric_limits::max(); expression_node_ptr result = error_node(); + std::string node_name = "Unknown"; if (no_psi == param_seq_index) + { result = node_allocator_->allocate(gf,arg_list); + node_name = "string_function_node"; + } else + { result = node_allocator_->allocate(gf, param_seq_index, arg_list); + node_name = "multimode_strfunction_node"; + } alloc_type1* strfunc_node_ptr = static_cast(result); + assert(strfunc_node_ptr); + if ( !arg_list.empty() && !gf->has_side_effects() && @@ -29770,9 +33761,20 @@ namespace exprtk } else if (strfunc_node_ptr->init_branches()) { - parser_->state_.activate_side_effect("string_function_call()"); + if (result && result->valid()) + { + parser_->state_.activate_side_effect("string_function_call()"); + return result; + } - return result; + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR262 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } else { @@ -29800,11 +33802,24 @@ namespace exprtk alloc_type* return_node_ptr = static_cast(result); + assert(return_node_ptr); + if (return_node_ptr->init_branches()) { - parser_->state_.activate_side_effect("return_call()"); + if (result && result->valid()) + { + parser_->state_.activate_side_effect("return_call()"); + return result; + } - return result; + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR263 - Failed to synthesize node: return_node", + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } else { @@ -29842,28 +33857,93 @@ namespace exprtk } #endif - inline expression_node_ptr vector_element(const std::string& symbol, - vector_holder_ptr vector_base, + inline expression_node_ptr vector_element(const std::string& symbol, + vector_holder_ptr vector_base, + expression_node_ptr vec_node, expression_node_ptr index) { expression_node_ptr result = error_node(); + std::string node_name = "Unknown"; if (details::is_constant_node(index)) { - std::size_t i = static_cast(details::numeric::to_int64(index->value())); + const std::size_t vec_index = static_cast(details::numeric::to_int64(index->value())); details::free_node(*node_allocator_,index); + if (vec_index >= vector_base->size()) + { + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + token_t(), + "ERR264 - Index of " + details::to_str(vec_index) + " out of range for " + "vector '" + symbol + "' of size " + details::to_str(vector_base->size()), + exprtk_error_location)); + + details::free_node(*node_allocator_,vec_node); + + return error_node(); + } + if (vector_base->rebaseable()) { - return node_allocator_->allocate(i,vector_base); + vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); + + result = (rtc) ? + node_allocator_->allocate(vec_node, vec_index, vector_base, rtc) : + node_allocator_->allocate(vec_node, vec_index, vector_base ) ; + + node_name = (rtc) ? + "rebasevector_elem_rtc_node_t" : + "rebasevector_elem_node_t" ; + + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR265 - Failed to synthesize node: " + node_name + " for vector: " + symbol, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); + } + else if (details::is_ivector_node(vec_node) && !details::is_vector_node(vec_node)) + { + vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); + + result = (rtc) ? + node_allocator_->allocate(vec_node, vec_index, vector_base, rtc) : + node_allocator_->allocate(vec_node, vec_index, vector_base ) ; + + node_name = (rtc) ? + "vector_elem_rtc_node_t" : + "vector_elem_node_t" ; + + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR266 - Failed to synthesize node: " + node_name + " for vector: " + symbol, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } - const scope_element& se = parser_->sem_.get_element(symbol,i); + const scope_element& se = parser_->sem_.get_element(symbol,vec_index); - if (se.index == i) + if (se.index == vec_index) { result = se.var_node; + details::free_node(*node_allocator_,vec_node); } else { @@ -29872,10 +33952,10 @@ namespace exprtk nse.active = true; nse.ref_count = 1; nse.type = scope_element::e_vecelem; - nse.index = i; + nse.index = vec_index; nse.depth = parser_->state_.scope_depth; nse.data = 0; - nse.var_node = node_allocator_->allocate((*(*vector_base)[i])); + nse.var_node = node_allocator_->allocate((*(*vector_base)[vec_index])); if (!parser_->sem_.add_element(nse)) { @@ -29886,19 +33966,55 @@ namespace exprtk result = error_node(); } - exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n",nse.name.c_str())); + details::free_node(*node_allocator_,vec_node); + + exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n", nse.name.c_str())); parser_->state_.activate_side_effect("vector_element()"); result = nse.var_node; + node_name = "variable_node_t"; } } - else if (vector_base->rebaseable()) - result = node_allocator_->allocate(index,vector_base); else - result = node_allocator_->allocate(index,vector_base); + { + vector_access_runtime_check_ptr rtc = get_vector_access_runtime_check(); - return result; + if (vector_base->rebaseable()) + { + result = (rtc) ? + node_allocator_->allocate(vec_node, index, vector_base, rtc) : + node_allocator_->allocate(vec_node, index, vector_base ) ; + + node_name = (rtc) ? + "rebasevector_elem_rtc_node_t" : + "rebasevector_elem_node_t" ; + } + else + { + result = rtc ? + node_allocator_->allocate(vec_node, index, vector_base, rtc) : + node_allocator_->allocate(vec_node, index, vector_base ) ; + + node_name = (rtc) ? + "vector_elem_rtc_node_t" : + "vector_elem_node_t" ; + } + } + + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR267 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } private: @@ -29995,12 +34111,27 @@ namespace exprtk case details::expression_node::e_vecelem: return reinterpret_cast(&static_cast(node)->ref()); + case details::expression_node::e_veccelem: + return reinterpret_cast(&static_cast(node)->ref()); + + case details::expression_node::e_vecelemrtc: + return reinterpret_cast(&static_cast(node)->ref()); + + case details::expression_node::e_veccelemrtc: + return reinterpret_cast(&static_cast(node)->ref()); + case details::expression_node::e_rbvecelem: return reinterpret_cast(&static_cast(node)->ref()); + case details::expression_node::e_rbvecelemrtc: + return reinterpret_cast(&static_cast(node)->ref()); + case details::expression_node::e_rbveccelem: return reinterpret_cast(&static_cast(node)->ref()); + case details::expression_node::e_rbveccelemrtc: + return reinterpret_cast(&static_cast(node)->ref()); + case details::expression_node::e_vector: return reinterpret_cast(static_cast(node)->vec_holder().data()); @@ -30032,11 +34163,11 @@ namespace exprtk if (parser_->immutable_symtok_map_.end() != itr) { token_t& token = itr->second; - parser_->set_error( - parser_error::make_error(parser_error::e_parser, - token, - "ERR211 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.", - exprtk_error_location)); + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + token, + "ERR268 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.", + exprtk_error_location)); } else parser_->set_synthesis_error("Unable to assign symbol is immutable."); @@ -30058,16 +34189,26 @@ namespace exprtk lodge_assignment(e_st_variable,branch[0]); return synthesize_expression(operation,branch); } - else if (details::is_vector_elem_node(branch[0])) + else if (details::is_vector_elem_node(branch[0]) || details::is_vector_celem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); return synthesize_expression(operation, branch); } + else if (details::is_vector_elem_rtc_node(branch[0]) || details::is_vector_celem_rtc_node(branch[0])) + { + lodge_assignment(e_st_vecelem,branch[0]); + return synthesize_expression(operation, branch); + } else if (details::is_rebasevector_elem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); return synthesize_expression(operation, branch); } + else if (details::is_rebasevector_elem_rtc_node(branch[0])) + { + lodge_assignment(e_st_vecelem,branch[0]); + return synthesize_expression(operation, branch); + } else if (details::is_rebasevector_celem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); @@ -30094,9 +34235,23 @@ namespace exprtk else return synthesize_expression(operation, branch); } + else if (details::is_literal_node(branch[0])) + { + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR269 - Cannot assign value to const variable", + exprtk_error_location)); + + return error_node(); + } else { - parser_->set_synthesis_error("Invalid assignment operation.[1]"); + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR270 - Invalid branches for assignment operator '" + details::to_str(operation) + "'", + exprtk_error_location)); return error_node(); } @@ -30110,6 +34265,9 @@ namespace exprtk return error_node(); } + expression_node_ptr result = error_node(); + std::string node_name = "Unknown"; + if (details::is_variable_node(branch[0])) { lodge_assignment(e_st_variable,branch[0]); @@ -30117,9 +34275,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "assignment_op_node"; \ + break; \ case_stmt(details::e_addass , details::add_op) case_stmt(details::e_subass , details::sub_op) @@ -30137,9 +34297,55 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "assignment_vec_elem_op_node"; \ + break; \ + + case_stmt(details::e_addass , details::add_op) + case_stmt(details::e_subass , details::sub_op) + case_stmt(details::e_mulass , details::mul_op) + case_stmt(details::e_divass , details::div_op) + case_stmt(details::e_modass , details::mod_op) + #undef case_stmt + default : return error_node(); + } + } + else if (details::is_vector_elem_rtc_node(branch[0])) + { + lodge_assignment(e_st_vecelem,branch[0]); + + switch (operation) + { + #define case_stmt(op0, op1) \ + case op0 : result = node_allocator_-> \ + template allocate_rrr > > \ + (operation, branch[0], branch[1]); \ + node_name = "assignment_vec_elem_op_rtc_node"; \ + break; \ + + case_stmt(details::e_addass , details::add_op) + case_stmt(details::e_subass , details::sub_op) + case_stmt(details::e_mulass , details::mul_op) + case_stmt(details::e_divass , details::div_op) + case_stmt(details::e_modass , details::mod_op) + #undef case_stmt + default : return error_node(); + } + } + else if (details::is_vector_celem_rtc_node(branch[0])) + { + lodge_assignment(e_st_vecelem,branch[0]); + + switch (operation) + { + #define case_stmt(op0, op1) \ + case op0 : result = node_allocator_-> \ + template allocate_rrr > > \ + (operation, branch[0], branch[1]); \ + node_name = "assignment_vec_celem_op_rtc_node"; \ + break; \ case_stmt(details::e_addass , details::add_op) case_stmt(details::e_subass , details::sub_op) @@ -30157,9 +34363,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "assignment_rebasevec_elem_op_node"; \ + break; \ case_stmt(details::e_addass , details::add_op) case_stmt(details::e_subass , details::sub_op) @@ -30177,9 +34385,55 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "assignment_rebasevec_celem_op_node"; \ + break; \ + + case_stmt(details::e_addass , details::add_op) + case_stmt(details::e_subass , details::sub_op) + case_stmt(details::e_mulass , details::mul_op) + case_stmt(details::e_divass , details::div_op) + case_stmt(details::e_modass , details::mod_op) + #undef case_stmt + default : return error_node(); + } + } + else if (details::is_rebasevector_elem_rtc_node(branch[0])) + { + lodge_assignment(e_st_vecelem,branch[0]); + + switch (operation) + { + #define case_stmt(op0, op1) \ + case op0 : result = node_allocator_-> \ + template allocate_rrr > > \ + (operation, branch[0], branch[1]); \ + node_name = "assignment_rebasevec_elem_op_rtc_node"; \ + break; \ + + case_stmt(details::e_addass , details::add_op) + case_stmt(details::e_subass , details::sub_op) + case_stmt(details::e_mulass , details::mul_op) + case_stmt(details::e_divass , details::div_op) + case_stmt(details::e_modass , details::mod_op) + #undef case_stmt + default : return error_node(); + } + } + else if (details::is_rebasevector_celem_rtc_node(branch[0])) + { + lodge_assignment(e_st_vecelem,branch[0]); + + switch (operation) + { + #define case_stmt(op0, op1) \ + case op0 : result = node_allocator_-> \ + template allocate_rrr > > \ + (operation, branch[0], branch[1]); \ + node_name = "assignment_rebasevec_celem_op_rtc_node"; \ + break; \ case_stmt(details::e_addass , details::add_op) case_stmt(details::e_subass , details::sub_op) @@ -30199,9 +34453,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "assignment_rebasevec_celem_op_node"; \ + break; \ case_stmt(details::e_addass , details::add_op) case_stmt(details::e_subass , details::sub_op) @@ -30217,9 +34473,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "assignment_vec_op_node"; \ + break; \ case_stmt(details::e_addass , details::add_op) case_stmt(details::e_subass , details::sub_op) @@ -30241,15 +34499,34 @@ namespace exprtk lodge_assignment(e_st_string,branch[0]); - return synthesize_expression(operation,branch); + result = synthesize_expression(operation,branch); + node_name = "assignment_string_node"; } #endif else { - parser_->set_synthesis_error("Invalid assignment operation[2]"); + parser_->set_error(parser_error::make_error( + parser_error::e_syntax, + parser_->current_state().token, + "ERR271 - Invalid branches for assignment operator '" + details::to_str(operation) + "'", + exprtk_error_location)); return error_node(); } + + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR272 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } inline expression_node_ptr synthesize_veceqineqlogic_operation_expression(const details::operator_type& operation, @@ -30273,14 +34550,19 @@ namespace exprtk case_stmt(details::e_xor , details::xor_op ) \ case_stmt(details::e_xnor , details::xnor_op ) \ + expression_node_ptr result = error_node(); + std::string node_name = "Unknown"; + if (is_b0_ivec && is_b1_ivec) { switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "vec_binop_vecvec_node"; \ + break; \ batch_eqineq_logic_case #undef case_stmt @@ -30292,9 +34574,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "vec_binop_vecval_node"; \ + break; \ batch_eqineq_logic_case #undef case_stmt @@ -30306,9 +34590,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "vec_binop_valvec_node"; \ + break; \ batch_eqineq_logic_case #undef case_stmt @@ -30318,6 +34604,20 @@ namespace exprtk else return error_node(); + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR273 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); + #undef batch_eqineq_logic_case } @@ -30334,14 +34634,19 @@ namespace exprtk case_stmt(details::e_div , details::div_op) \ case_stmt(details::e_mod , details::mod_op) \ + expression_node_ptr result = error_node(); + std::string node_name = "Unknown"; + if (is_b0_ivec && is_b1_ivec) { switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "vec_binop_vecvec_node"; \ + break; \ vector_ops case_stmt(details::e_pow,details:: pow_op) @@ -30354,9 +34659,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "vec_binop_vecval_node(b0ivec,!b1ivec)"; \ + break; \ vector_ops case_stmt(details::e_pow,details:: pow_op) @@ -30369,9 +34676,11 @@ namespace exprtk switch (operation) { #define case_stmt(op0, op1) \ - case op0 : return node_allocator_-> \ + case op0 : result = node_allocator_-> \ template allocate_rrr > > \ (operation, branch[0], branch[1]); \ + node_name = "vec_binop_vecval_node(!b0ivec,b1ivec)"; \ + break; \ vector_ops #undef case_stmt @@ -30381,6 +34690,20 @@ namespace exprtk else return error_node(); + if (result && result->valid()) + { + return result; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR274 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); + #undef vector_ops } @@ -30398,6 +34721,7 @@ namespace exprtk #endif expression_node_ptr result = error_node(); + std::string node_name = "Unknown"; if (v0_is_ivar && v1_is_ivar) { @@ -30411,36 +34735,57 @@ namespace exprtk (0 != (v1 = dynamic_cast(branch[1]))) ) { - result = node_allocator_->allocate >(v0,v1); + result = node_allocator_->allocate >(v0,v1); + node_name = "swap_node"; } else - result = node_allocator_->allocate >(branch[0],branch[1]); + { + result = node_allocator_->allocate >(branch[0],branch[1]); + node_name = "swap_generic_node"; + } } else if (v0_is_ivec && v1_is_ivec) { - result = node_allocator_->allocate >(branch[0],branch[1]); + result = node_allocator_->allocate >(branch[0],branch[1]); + node_name = "swap_vecvec_node"; } #ifndef exprtk_disable_string_capabilities else if (v0_is_str && v1_is_str) { if (is_string_node(branch[0]) && is_string_node(branch[1])) + { result = node_allocator_->allocate > (branch[0], branch[1]); + node_name = "swap_string_node"; + } else + { result = node_allocator_->allocate > (branch[0], branch[1]); + node_name = "swap_genstrings_node"; + } } #endif else { parser_->set_synthesis_error("Only variables, strings, vectors or vector elements can be swapped"); - return error_node(); } - parser_->state_.activate_side_effect("synthesize_swap_expression()"); + if (result && result->valid()) + { + parser_->state_.activate_side_effect("synthesize_swap_expression()"); + return result; + } - return result; + parser_->set_error(parser_error::make_error( + parser_error::e_synthesis, + token_t(), + "ERR275 - Failed to synthesize node: " + node_name, + exprtk_error_location)); + + details::free_node(*node_allocator_, result); + return error_node(); } #ifndef exprtk_disable_sc_andor @@ -30596,7 +34941,7 @@ namespace exprtk else if (not_recipricol) return cardinal_pow_optimisation_impl(branch[0],p); else - return cardinal_pow_optimisation_impl(branch[0],p); + return cardinal_pow_optimisation_impl(branch[0],p); } #else inline expression_node_ptr cardinal_pow_optimisation(T&, const T&) @@ -31969,9 +36314,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t"; } }; @@ -32034,9 +36379,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)"; } }; @@ -32100,9 +36445,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t"; } }; @@ -32165,9 +36510,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)"; } }; @@ -32230,9 +36575,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t"; } }; @@ -32295,9 +36640,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)"; } }; @@ -32360,9 +36705,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t"; } }; @@ -32426,9 +36771,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)"; } }; @@ -32545,9 +36890,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t"; } }; @@ -32664,9 +37009,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)"; } }; @@ -32795,9 +37140,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)"; } }; @@ -32922,9 +37267,9 @@ namespace exprtk const details::operator_type o1) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t"; } }; @@ -33057,10 +37402,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -33146,10 +37491,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -33235,10 +37580,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -33324,10 +37669,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -33413,10 +37758,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -33607,10 +37952,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -33851,10 +38196,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -34045,10 +38390,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -34238,10 +38583,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t)"; + << "(t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t)"; } }; @@ -34298,10 +38643,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34358,10 +38703,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34418,10 +38763,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34478,10 +38823,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34539,10 +38884,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34600,10 +38945,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34660,10 +39005,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34720,10 +39065,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34780,10 +39125,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "(t" << expr_gen.to_str(o2) - << "t))"; + << "t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "(t" << expr_gen.to_str(o2) + << "t))"; } }; @@ -34840,10 +39185,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -34900,10 +39245,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -34960,10 +39305,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -35020,10 +39365,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -35081,10 +39426,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -35142,10 +39487,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -35202,10 +39547,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -35263,10 +39608,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "t" << expr_gen.to_str(o0) - << "((t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t)"; + << "t" << expr_gen.to_str(o0) + << "((t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t)"; } }; @@ -35344,10 +39689,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35405,10 +39750,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35465,10 +39810,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35525,10 +39870,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35585,10 +39930,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35645,10 +39990,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35706,10 +40051,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35767,10 +40112,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35827,10 +40172,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "((t" << expr_gen.to_str(o0) - << "t)" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "((t" << expr_gen.to_str(o0) + << "t)" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35887,10 +40232,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -35948,10 +40293,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -36008,10 +40353,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -36067,10 +40412,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -36127,10 +40472,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -36187,10 +40532,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -36248,10 +40593,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -36309,10 +40654,10 @@ namespace exprtk const details::operator_type o2) { return details::build_string() - << "(t" << expr_gen.to_str(o0) - << "(t" << expr_gen.to_str(o1) - << "t)" << expr_gen.to_str(o2) - << "t"; + << "(t" << expr_gen.to_str(o0) + << "(t" << expr_gen.to_str(o1) + << "t)" << expr_gen.to_str(o2) + << "t"; } }; @@ -36737,6 +41082,8 @@ namespace exprtk default : return error_node(); } } + + #undef string_opr_switch_statements #endif #ifndef exprtk_disable_string_capabilities @@ -37070,11 +41417,22 @@ namespace exprtk return node_allocator_->allocate(v); } - else + + if (expression_point && expression_point->valid()) + { return expression_point; + } + + parser_->set_error(parser_error::make_error( + parser_error::e_parser, + token_t(), + "ERR276 - Failed to synthesize node: NodeType", + exprtk_error_location)); + + details::free_node(*node_allocator_, expression_point); } - else - return error_node(); + + return error_node(); } template @@ -37154,8 +41512,11 @@ namespace exprtk { scope_element& se = sem_.get_element(i); + exprtk_debug(("register_local_vars() - se[%s]\n", se.name.c_str())); + if ( (scope_element::e_variable == se.type) || + (scope_element::e_literal == se.type) || (scope_element::e_vecelem == se.type) ) { @@ -37428,6 +41789,7 @@ namespace exprtk sf4_map_t sf4_map_; std::string synthesis_error_; scope_element_manager sem_; + std::vector current_state_stack_; immutable_memory_map_t immutable_memory_map_; immutable_symtok_map_t immutable_symtok_map_; @@ -37443,7 +41805,11 @@ namespace exprtk lexer::helper::sequence_validator sequence_validator_; lexer::helper::sequence_validator_3tokens sequence_validator_3tkns_; - loop_runtime_check_ptr loop_runtime_check_; + loop_runtime_check_ptr loop_runtime_check_; + vector_access_runtime_check_ptr vector_access_runtime_check_; + compilation_check_ptr compilation_check_ptr_; + assert_check_ptr assert_check_; + std::set assert_ids_; template friend void details::disable_type_checking(ParserType& p); @@ -37460,17 +41826,19 @@ namespace exprtk typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t; typedef typename parser_t::unknown_symbol_resolver usr_t; - struct resolve_as_vector : public parser_t::unknown_symbol_resolver + struct resolve_as_vector : public usr_t { typedef exprtk::parser parser_t; + using usr_t::process; + resolve_as_vector() : usr_t(usr_t::e_usrmode_extended) {} virtual bool process(const std::string& unknown_symbol, symbol_table_t& symbol_table, - std::string&) + std::string&) exprtk_override { static T v[1]; symbol_table.add_vector(unknown_symbol,v); @@ -37682,7 +42050,9 @@ namespace exprtk const symbol_table& sym_table = e.get_symbol_table(); if (!sym_table.valid()) + { return std::numeric_limits::quiet_NaN(); + } details::variable_node* var = sym_table.get_variable(variable_name); @@ -37695,8 +42065,8 @@ namespace exprtk return result; } - else - return std::numeric_limits::quiet_NaN(); + + return std::numeric_limits::quiet_NaN(); } template @@ -37786,8 +42156,8 @@ namespace exprtk return result; } - else - return std::numeric_limits::quiet_NaN(); + + return std::numeric_limits::quiet_NaN(); } template @@ -37813,8 +42183,8 @@ namespace exprtk return result; } - else - return std::numeric_limits::quiet_NaN(); + + return std::numeric_limits::quiet_NaN(); } template @@ -37840,8 +42210,8 @@ namespace exprtk return result; } - else - return std::numeric_limits::quiet_NaN(); + + return std::numeric_limits::quiet_NaN(); } /* @@ -38120,97 +42490,98 @@ namespace exprtk disable_has_side_effects(*this); } - virtual ~polynomial() {} + virtual ~polynomial() + {} #define poly_rtrn(NN) \ return (NN != N) ? std::numeric_limits::quiet_NaN() : - inline virtual T operator() (const T& x, const T& c1, const T& c0) + inline virtual T operator() (const T& x, const T& c1, const T& c0) exprtk_override { poly_rtrn(1) (poly_impl::evaluate(x, c1, c0)); } - inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) + inline virtual T operator() (const T& x, const T& c2, const T& c1, const T& c0) exprtk_override { poly_rtrn(2) (poly_impl::evaluate(x, c2, c1, c0)); } - inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) + inline virtual T operator() (const T& x, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override { poly_rtrn(3) (poly_impl::evaluate(x, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c4, const T& c3, const T& c2, const T& c1, - const T& c0) + const T& c0) exprtk_override { poly_rtrn(4) (poly_impl::evaluate(x, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c5, const T& c4, const T& c3, const T& c2, - const T& c1, const T& c0) + const T& c1, const T& c0) exprtk_override { poly_rtrn(5) (poly_impl::evaluate(x, c5, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c6, const T& c5, const T& c4, const T& c3, - const T& c2, const T& c1, const T& c0) + const T& c2, const T& c1, const T& c0) exprtk_override { poly_rtrn(6) (poly_impl::evaluate(x, c6, c5, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c7, const T& c6, const T& c5, const T& c4, - const T& c3, const T& c2, const T& c1, const T& c0) + const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override { poly_rtrn(7) (poly_impl::evaluate(x, c7, c6, c5, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c8, const T& c7, const T& c6, const T& c5, - const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) + const T& c4, const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override { poly_rtrn(8) (poly_impl::evaluate(x, c8, c7, c6, c5, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, const T& c1, - const T& c0) + const T& c0) exprtk_override { poly_rtrn(9) (poly_impl::evaluate(x, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, const T& c2, - const T& c1, const T& c0) + const T& c1, const T& c0) exprtk_override { poly_rtrn(10) (poly_impl::evaluate(x, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c11, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, const T& c3, - const T& c2, const T& c1, const T& c0) + const T& c2, const T& c1, const T& c0) exprtk_override { poly_rtrn(11) (poly_impl::evaluate(x, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); } inline virtual T operator() (const T& x, const T& c12, const T& c11, const T& c10, const T& c9, const T& c8, const T& c7, const T& c6, const T& c5, const T& c4, - const T& c3, const T& c2, const T& c1, const T& c0) + const T& c3, const T& c2, const T& c1, const T& c0) exprtk_override { poly_rtrn(12) (poly_impl::evaluate(x, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0)); } #undef poly_rtrn - inline virtual T operator() () + inline virtual T operator() () exprtk_override { return std::numeric_limits::quiet_NaN(); } - inline virtual T operator() (const T&) + inline virtual T operator() (const T&) exprtk_override { return std::numeric_limits::quiet_NaN(); } - inline virtual T operator() (const T&, const T&) + inline virtual T operator() (const T&, const T&) exprtk_override { return std::numeric_limits::quiet_NaN(); } @@ -38312,6 +42683,50 @@ namespace exprtk return (*this); } + inline function& vars(const std::string& v0, + const std::string& v1) + { + v_.push_back(v0); + v_.push_back(v1); + return (*this); + } + + inline function& vars(const std::string& v0, + const std::string& v1, + const std::string& v2) + { + v_.push_back(v0); + v_.push_back(v1); + v_.push_back(v2); + return (*this); + } + + inline function& vars(const std::string& v0, + const std::string& v1, + const std::string& v2, + const std::string& v3) + { + v_.push_back(v0); + v_.push_back(v1); + v_.push_back(v2); + v_.push_back(v3); + return (*this); + } + + inline function& vars(const std::string& v0, + const std::string& v1, + const std::string& v2, + const std::string& v3, + const std::string& v4) + { + v_.push_back(v0); + v_.push_back(v1); + v_.push_back(v2); + v_.push_back(v3); + v_.push_back(v4); + return (*this); + } + std::string name_; std::string expression_; std::deque v_; @@ -38321,12 +42736,14 @@ namespace exprtk struct base_func : public exprtk::ifunction { - typedef const T& type; - typedef exprtk::ifunction function_t; - typedef std::vector varref_t; - typedef std::vector var_t; + typedef const T& type; + typedef exprtk::ifunction function_t; + typedef std::vector varref_t; + typedef std::vector var_t; + typedef std::vector str_t; typedef std::pair lvarref_t; typedef std::vector lvr_vec_t; + typedef std::vector lstr_vec_t; using exprtk::ifunction::operator(); @@ -38338,10 +42755,11 @@ namespace exprtk v.resize(pc); } - virtual ~base_func() {} + virtual ~base_func() + {} - #define exprtk_assign(Index) \ - (*v[Index]) = v##Index; \ + #define exprtk_assign(Index) \ + (*v[Index]) = v##Index; \ inline void update(const T& v0) { @@ -38387,17 +42805,33 @@ namespace exprtk { expression = expr; - typedef typename expression_t::control_block::local_data_list_t ldl_t; + typedef typename expression_t::control_block ctrlblk_t; + typedef typename ctrlblk_t::local_data_list_t ldl_t; + typedef typename ctrlblk_t::data_type data_t; + typedef typename ldl_t::value_type ldl_value_type; const ldl_t ldl = expr.local_data_list(); - std::vector index_list; + std::vector > index_list; for (std::size_t i = 0; i < ldl.size(); ++i) { + exprtk_debug(("base_func::setup() - element[%02d] type: %s size: %d\n", + static_cast(i), + expression_t::control_block::to_str(ldl[i].type).c_str(), + static_cast(ldl[i].size))); + + switch (ldl[i].type) + { + case ctrlblk_t::e_unknown : continue; + case ctrlblk_t::e_expr : continue; + case ctrlblk_t::e_vecholder : continue; + default : break; + } + if (ldl[i].size) { - index_list.push_back(i); + index_list.push_back(std::make_pair(i,ldl[i].type)); } } @@ -38405,19 +42839,34 @@ namespace exprtk for (std::size_t i = 0; i < index_list.size(); ++i) { - const std::size_t index = index_list[i]; + const std::size_t index = index_list[i].first; + const ldl_value_type& local_var = ldl[index]; + + assert(local_var.pointer); if (i < (index_list.size() - v.size())) { - lv.push_back( - std::make_pair( - reinterpret_cast(ldl[index].pointer), - ldl[index].size)); + if (local_var.type == ctrlblk_t::e_string) + { + local_str_vars.push_back( + reinterpret_cast(local_var.pointer)); + } + else if ( + (local_var.type == ctrlblk_t::e_data ) || + (local_var.type == ctrlblk_t::e_vecdata) + ) + { + local_vars.push_back(std::make_pair( + reinterpret_cast(local_var.pointer), + local_var.size)); - local_var_stack_size += ldl[index].size; + local_var_stack_size += local_var.size; + } } else - v[input_param_count++] = reinterpret_cast(ldl[index].pointer); + { + v[input_param_count++] = reinterpret_cast(local_var.pointer); + } } clear_stack(); @@ -38433,14 +42882,21 @@ namespace exprtk { var_t var_stack(v.size(),T(0)); copy(v,var_stack); - param_stack.push_back(var_stack); + input_params_stack.push_back(var_stack); + } + + if (!local_vars.empty()) + { + var_t local_vec_frame(local_var_stack_size,T(0)); + copy(local_vars,local_vec_frame); + local_var_stack.push_back(local_vec_frame); } - if (!lv.empty()) + if (!local_str_vars.empty()) { - var_t local_var_stack(local_var_stack_size,T(0)); - copy(lv,local_var_stack); - local_stack.push_back(local_var_stack); + str_t local_str_frame(local_str_vars.size()); + copy(local_str_vars,local_str_frame); + local_str_stack.push_back(local_str_frame); } } } @@ -38451,14 +42907,20 @@ namespace exprtk { if (!v.empty()) { - copy(param_stack.back(),v); - param_stack.pop_back(); + copy(input_params_stack.back(), v); + input_params_stack.pop_back(); } - if (!lv.empty()) + if (!local_vars.empty()) { - copy(local_stack.back(),lv); - local_stack.pop_back(); + copy(local_var_stack.back(), local_vars); + local_var_stack.pop_back(); + } + + if (!local_str_vars.empty()) + { + copy(local_str_stack.back(), local_str_vars); + local_str_stack.pop_back(); } } } @@ -38471,6 +42933,14 @@ namespace exprtk } } + void copy(const lstr_vec_t& src_v, str_t& dest_v) + { + for (std::size_t i = 0; i < src_v.size(); ++i) + { + dest_v[i] = (*src_v[i]); + } + } + void copy(const var_t& src_v, varref_t& dest_v) { for (std::size_t i = 0; i < src_v.size(); ++i) @@ -38503,9 +42973,12 @@ namespace exprtk typename var_t::const_iterator itr = src_v.begin(); typedef typename std::iterator_traits::difference_type diff_t; - for (std::size_t i = 0; i < src_v.size(); ++i) + for (std::size_t i = 0; i < dest_v.size(); ++i) { - lvarref_t vr = dest_v[i]; + lvarref_t& vr = dest_v[i]; + + assert(vr.first != 0); + assert(vr.second > 0); if (1 == vr.second) (*vr.first) = *itr++; @@ -38517,6 +42990,16 @@ namespace exprtk } } + void copy(const str_t& src_str, lstr_vec_t& dest_str) + { + assert(src_str.size() == dest_str.size()); + + for (std::size_t i = 0; i < dest_str.size(); ++i) + { + *dest_str[i] = src_str[i]; + } + } + inline void clear_stack() { for (std::size_t i = 0; i < v.size(); ++i) @@ -38530,29 +43013,19 @@ namespace exprtk return e.value(); } - expression_t expression; - varref_t v; - lvr_vec_t lv; - std::size_t local_var_stack_size; - std::size_t stack_depth; - std::deque param_stack; - std::deque local_stack; + expression_t expression; + varref_t v; + lvr_vec_t local_vars; + lstr_vec_t local_str_vars; + std::size_t local_var_stack_size; + std::size_t stack_depth; + std::deque input_params_stack; + std::deque local_var_stack; + std::deque local_str_stack; }; typedef std::map funcparam_t; - struct func_0param : public base_func - { - using exprtk::ifunction::operator(); - - func_0param() : base_func(0) {} - - inline T operator() () - { - return this->value(base_func::expression); - } - }; - typedef const T& type; template @@ -38577,13 +43050,26 @@ namespace exprtk scoped_bft& operator=(const scoped_bft&) exprtk_delete; }; + struct func_0param : public base_func + { + using exprtk::ifunction::operator(); + + func_0param() : base_func(0) {} + + inline T operator() () exprtk_override + { + scoped_bft sb(*this); + return this->value(base_func::expression); + } + }; + struct func_1param : public base_func { using exprtk::ifunction::operator(); func_1param() : base_func(1) {} - inline T operator() (type v0) + inline T operator() (type v0) exprtk_override { scoped_bft sb(*this); base_func::update(v0); @@ -38597,7 +43083,7 @@ namespace exprtk func_2param() : base_func(2) {} - inline T operator() (type v0, type v1) + inline T operator() (type v0, type v1) exprtk_override { scoped_bft sb(*this); base_func::update(v0, v1); @@ -38611,7 +43097,7 @@ namespace exprtk func_3param() : base_func(3) {} - inline T operator() (type v0, type v1, type v2) + inline T operator() (type v0, type v1, type v2) exprtk_override { scoped_bft sb(*this); base_func::update(v0, v1, v2); @@ -38625,7 +43111,7 @@ namespace exprtk func_4param() : base_func(4) {} - inline T operator() (type v0, type v1, type v2, type v3) + inline T operator() (type v0, type v1, type v2, type v3) exprtk_override { scoped_bft sb(*this); base_func::update(v0, v1, v2, v3); @@ -38639,7 +43125,7 @@ namespace exprtk func_5param() : base_func(5) {} - inline T operator() (type v0, type v1, type v2, type v3, type v4) + inline T operator() (type v0, type v1, type v2, type v3, type v4) exprtk_override { scoped_bft sb(*this); base_func::update(v0, v1, v2, v3, v4); @@ -38653,7 +43139,7 @@ namespace exprtk func_6param() : base_func(6) {} - inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) + inline T operator() (type v0, type v1, type v2, type v3, type v4, type v5) exprtk_override { scoped_bft sb(*this); base_func::update(v0, v1, v2, v3, v4, v5); @@ -38680,14 +43166,14 @@ namespace exprtk return result; } - #define def_fp_retval(N) \ - struct func_##N##param_retval : public func_##N##param \ - { \ - inline T value(expression_t& e) \ - { \ - return return_value(e); \ - } \ - }; \ + #define def_fp_retval(N) \ + struct func_##N##param_retval exprtk_final : public func_##N##param \ + { \ + inline T value(expression_t& e) exprtk_override \ + { \ + return return_value(e); \ + } \ + }; \ def_fp_retval(0) def_fp_retval(1) @@ -38697,6 +43183,8 @@ namespace exprtk def_fp_retval(5) def_fp_retval(6) + #undef def_fp_retval + template class Sequence> inline bool add(const std::string& name, @@ -38739,16 +43227,20 @@ namespace exprtk public: function_compositor() - : parser_(settings_t::compile_all_opts + + : parser_(settings_t::default_compile_all_opts + settings_t::e_disable_zero_return) , fp_map_(7) + , load_variables_(false) + , load_vectors_(false) {} - function_compositor(const symbol_table_t& st) + explicit function_compositor(const symbol_table_t& st) : symbol_table_(st) - , parser_(settings_t::compile_all_opts + + , parser_(settings_t::default_compile_all_opts + settings_t::e_disable_zero_return) , fp_map_(7) + , load_variables_(false) + , load_vectors_(false) {} ~function_compositor() @@ -38771,6 +43263,46 @@ namespace exprtk auxiliary_symtab_list_.push_back(&symtab); } + void load_variables(const bool load = true) + { + load_variables_ = load; + } + + void load_vectors(const bool load = true) + { + load_vectors_ = load; + } + + inline void register_loop_runtime_check(loop_runtime_check& lrtchk) + { + parser_.register_loop_runtime_check(lrtchk); + } + + inline void register_vector_access_runtime_check(vector_access_runtime_check& vartchk) + { + parser_.register_vector_access_runtime_check(vartchk); + } + + inline void register_compilation_timeout_check(compilation_check& compchk) + { + parser_.register_compilation_timeout_check(compchk); + } + + inline void clear_loop_runtime_check() + { + parser_.clear_loop_runtime_check(); + } + + inline void clear_vector_access_runtime_check() + { + parser_.clear_vector_access_runtime_check(); + } + + inline void clear_compilation_timeout_check() + { + parser_.clear_compilation_timeout_check(); + } + void clear() { symbol_table_.clear(); @@ -38789,6 +43321,10 @@ namespace exprtk fp_map_[i].clear(); } + + clear_loop_runtime_check (); + clear_vector_access_runtime_check(); + clear_compilation_timeout_check (); } inline bool add(const function& f, const bool override = false) @@ -38796,6 +43332,31 @@ namespace exprtk return add(f.name_, f.expression_, f.v_,override); } + inline std::string error() const + { + if (!error_list_.empty()) + { + return error_list_[0].diagnostic; + } + else + return std::string("No Error"); + } + + inline std::size_t error_count() const + { + return error_list_.size(); + } + + inline parser_error::type get_error(const std::size_t& index) const + { + if (index < error_list_.size()) + { + return error_list_[index]; + } + + throw std::invalid_argument("compositor::get_error() - Invalid error index specified"); + } + private: template expr_map_; std::vector fp_map_; std::vector auxiliary_symtab_list_; + std::deque error_list_; + bool load_variables_; + bool load_vectors_; }; // class function_compositor } // namespace exprtk -#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) # ifndef NOMINMAX # define NOMINMAX # endif @@ -39001,9 +43591,11 @@ namespace exprtk { public: - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) timer() : in_use_(false) + , start_time_{ {0, 0} } + , stop_time_ { {0, 0} } { QueryPerformanceFrequency(&clock_frequency_); } @@ -39081,7 +43673,7 @@ namespace exprtk bool in_use_; - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + #if defined(_MSC_VER) || defined(_WIN32) || defined(__WIN32__) || defined(WIN32) LARGE_INTEGER start_time_; LARGE_INTEGER stop_time_; LARGE_INTEGER clock_frequency_; @@ -39114,7 +43706,23 @@ namespace exprtk const T v, exprtk::details::numeric::details::real_type_tag) { - printf(fmt.c_str(),v); + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wformat-nonliteral" + #elif defined(__GNUC__) || defined(__GNUG__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + #elif defined(_MSC_VER) + #endif + + printf(fmt.c_str(), v); + + #if defined(__clang__) + #pragma clang diagnostic pop + #elif defined(__GNUC__) || defined(__GNUG__) + #pragma GCC diagnostic pop + #elif defined(_MSC_VER) + #endif } template @@ -39174,19 +43782,19 @@ namespace exprtk } // namespace exprtk::rtl::io::details template - struct print : public exprtk::igeneric_function + struct print exprtk_final : public exprtk::igeneric_function { typedef typename igeneric_function::parameter_list_t parameter_list_t; using exprtk::igeneric_function::operator(); - print(const std::string& scalar_format = "%10.5f") + explicit print(const std::string& scalar_format = "%10.5f") : scalar_format_(scalar_format) { exprtk::enable_zero_parameters(*this); } - inline T operator() (parameter_list_t parameters) + inline T operator() (parameter_list_t parameters) exprtk_override { details::print_impl::process(scalar_format_,parameters); return T(0); @@ -39196,19 +43804,19 @@ namespace exprtk }; template - struct println : public exprtk::igeneric_function + struct println exprtk_final : public exprtk::igeneric_function { typedef typename igeneric_function::parameter_list_t parameter_list_t; using exprtk::igeneric_function::operator(); - println(const std::string& scalar_format = "%10.5f") + explicit println(const std::string& scalar_format = "%10.5f") : scalar_format_(scalar_format) { exprtk::enable_zero_parameters(*this); } - inline T operator() (parameter_list_t parameters) + inline T operator() (parameter_list_t parameters) exprtk_override { details::print_impl::process(scalar_format_,parameters); printf("\n"); @@ -39290,8 +43898,8 @@ namespace exprtk return false; } - else - stream_ptr = stream; + + stream_ptr = stream; return true; } @@ -39306,8 +43914,8 @@ namespace exprtk return false; } - else - stream_ptr = stream; + + stream_ptr = stream; return true; } @@ -39322,13 +43930,13 @@ namespace exprtk return false; } - else - stream_ptr = stream; + + stream_ptr = stream; return true; } - else - return false; + + return false; } template @@ -39475,12 +44083,13 @@ namespace exprtk #ifdef _MSC_VER #pragma warning(pop) #endif + assert(sizeof(T) <= sizeof(void*)); } } // namespace exprtk::rtl::io::file::details template - class open : public exprtk::igeneric_function + class open exprtk_final : public exprtk::igeneric_function { public: @@ -39489,18 +44098,20 @@ namespace exprtk typedef typename igfun_t::generic_type generic_type; typedef typename generic_type::string_view string_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); open() : exprtk::igeneric_function("S|SS") { details::perform_check(); } - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const std::string file_name = to_str(string_t(parameters[0])); if (file_name.empty()) + { return T(0); + } if ((1 == ps_index) && (0 == string_t(parameters[1]).size())) { @@ -39532,7 +44143,7 @@ namespace exprtk }; template - struct close : public exprtk::ifunction + struct close exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); @@ -39540,7 +44151,7 @@ namespace exprtk : exprtk::ifunction(1) { details::perform_check(); } - inline T operator() (const T& v) + inline T operator() (const T& v) exprtk_override { details::file_descriptor* fd = details::make_handle(v); @@ -39554,7 +44165,7 @@ namespace exprtk }; template - class write : public exprtk::igeneric_function + class write exprtk_final : public exprtk::igeneric_function { public: @@ -39565,13 +44176,13 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); write() : igfun_t("TS|TST|TV|TVT") { details::perform_check(); } - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); @@ -39611,7 +44222,7 @@ namespace exprtk }; template - class read : public exprtk::igeneric_function + class read exprtk_final : public exprtk::igeneric_function { public: @@ -39622,13 +44233,13 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); read() : igfun_t("TS|TST|TV|TVT") { details::perform_check(); } - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); @@ -39668,7 +44279,7 @@ namespace exprtk }; template - class getline : public exprtk::igeneric_function + class getline exprtk_final : public exprtk::igeneric_function { public: @@ -39678,14 +44289,13 @@ namespace exprtk typedef typename generic_type::string_view string_t; typedef typename generic_type::scalar_view scalar_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); getline() : igfun_t("T",igfun_t::e_rtrn_string) { details::perform_check(); } - inline T operator() (std::string& result, - parameter_list_t parameters) + inline T operator() (std::string& result, parameter_list_t parameters) exprtk_override { details::file_descriptor* fd = details::make_handle(scalar_t(parameters[0])()); return T(fd->getline(result) ? 1 : 0); @@ -39693,7 +44303,7 @@ namespace exprtk }; template - struct eof : public exprtk::ifunction + struct eof exprtk_final : public exprtk::ifunction { using exprtk::ifunction::operator(); @@ -39701,10 +44311,9 @@ namespace exprtk : exprtk::ifunction(1) { details::perform_check(); } - inline T operator() (const T& v) + inline T operator() (const T& v) exprtk_override { details::file_descriptor* fd = details::make_handle(v); - return (fd->eof() ? T(1) : T(0)); } }; @@ -39814,44 +44423,61 @@ namespace exprtk } // namespace exprtk::rtl::details template - class all_true : public exprtk::igeneric_function + class all_true exprtk_final : public exprtk::igeneric_function { public: typedef typename exprtk::igeneric_function igfun_t; typedef typename igfun_t::parameter_list_t parameter_list_t; typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); all_true() - : exprtk::igeneric_function("V|VTT") + : exprtk::igeneric_function("V|VTT|T*") /* Overloads: 0. V - vector 1. VTT - vector, r0, r1 + 2. T* - T....T */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { - const vector_t vec(parameters[0]); + if (2 == ps_index) + { + for (std::size_t i = 0; i < parameters.size(); ++i) + { + if (scalar_t(parameters[i])() == T(0)) + { + return T(0); + } + } + } + else + { + const vector_t vec(parameters[0]); - std::size_t r0 = 0; - std::size_t r1 = vec.size() - 1; + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; - if ( - (1 == ps_index) && - !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) - ) - return std::numeric_limits::quiet_NaN(); + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { + return std::numeric_limits::quiet_NaN(); + } - for (std::size_t i = r0; i <= r1; ++i) - { - if (vec[i] == T(0)) + for (std::size_t i = r0; i <= r1; ++i) { - return T(0); + if (vec[i] == T(0)) + { + return T(0); + } } } @@ -39860,44 +44486,61 @@ namespace exprtk }; template - class all_false : public exprtk::igeneric_function + class all_false exprtk_final : public exprtk::igeneric_function { public: typedef typename exprtk::igeneric_function igfun_t; typedef typename igfun_t::parameter_list_t parameter_list_t; typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); all_false() - : exprtk::igeneric_function("V|VTT") + : exprtk::igeneric_function("V|VTT|T*") /* Overloads: 0. V - vector 1. VTT - vector, r0, r1 + 2. T* - T....T */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { - const vector_t vec(parameters[0]); + if (2 == ps_index) + { + for (std::size_t i = 0; i < parameters.size(); ++i) + { + if (scalar_t(parameters[i])() != T(0)) + { + return T(0); + } + } + } + else + { + const vector_t vec(parameters[0]); - std::size_t r0 = 0; - std::size_t r1 = vec.size() - 1; + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; - if ( - (1 == ps_index) && - !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) - ) - return std::numeric_limits::quiet_NaN(); + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { + return std::numeric_limits::quiet_NaN(); + } - for (std::size_t i = r0; i <= r1; ++i) - { - if (vec[i] != T(0)) + for (std::size_t i = r0; i <= r1; ++i) { - return T(0); + if (vec[i] != T(0)) + { + return T(0); + } } } @@ -39906,44 +44549,61 @@ namespace exprtk }; template - class any_true : public exprtk::igeneric_function + class any_true exprtk_final : public exprtk::igeneric_function { public: typedef typename exprtk::igeneric_function igfun_t; typedef typename igfun_t::parameter_list_t parameter_list_t; typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); any_true() - : exprtk::igeneric_function("V|VTT") + : exprtk::igeneric_function("V|VTT|T*") /* Overloads: 0. V - vector 1. VTT - vector, r0, r1 + 2. T* - T....T */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { - const vector_t vec(parameters[0]); + if (2 == ps_index) + { + for (std::size_t i = 0; i < parameters.size(); ++i) + { + if (scalar_t(parameters[i])() != T(0)) + { + return T(1); + } + } + } + else + { + const vector_t vec(parameters[0]); - std::size_t r0 = 0; - std::size_t r1 = vec.size() - 1; + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; - if ( - (1 == ps_index) && - !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) - ) - return std::numeric_limits::quiet_NaN(); + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { + return std::numeric_limits::quiet_NaN(); + } - for (std::size_t i = r0; i <= r1; ++i) - { - if (vec[i] != T(0)) + for (std::size_t i = r0; i <= r1; ++i) { - return T(1); + if (vec[i] != T(0)) + { + return T(1); + } } } @@ -39952,44 +44612,61 @@ namespace exprtk }; template - class any_false : public exprtk::igeneric_function + class any_false exprtk_final : public exprtk::igeneric_function { public: typedef typename exprtk::igeneric_function igfun_t; typedef typename igfun_t::parameter_list_t parameter_list_t; typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); any_false() - : exprtk::igeneric_function("V|VTT") + : exprtk::igeneric_function("V|VTT|T*") /* Overloads: 0. V - vector 1. VTT - vector, r0, r1 + 2. T* - T....T */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { - const vector_t vec(parameters[0]); + if (2 == ps_index) + { + for (std::size_t i = 0; i < parameters.size(); ++i) + { + if (scalar_t(parameters[i])() == T(0)) + { + return T(1); + } + } + } + else + { + const vector_t vec(parameters[0]); - std::size_t r0 = 0; - std::size_t r1 = vec.size() - 1; + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; - if ( - (1 == ps_index) && - !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) - ) - return std::numeric_limits::quiet_NaN(); + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { + return std::numeric_limits::quiet_NaN(); + } - for (std::size_t i = r0; i <= r1; ++i) - { - if (vec[i] == T(0)) + for (std::size_t i = r0; i <= r1; ++i) { - return T(1); + if (vec[i] == T(0)) + { + return T(1); + } } } @@ -39998,44 +44675,58 @@ namespace exprtk }; template - class count : public exprtk::igeneric_function + class count exprtk_final : public exprtk::igeneric_function { public: typedef typename exprtk::igeneric_function igfun_t; typedef typename igfun_t::parameter_list_t parameter_list_t; typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); count() - : exprtk::igeneric_function("V|VTT") + : exprtk::igeneric_function("V|VTT|T*") /* Overloads: 0. V - vector 1. VTT - vector, r0, r1 + 2. T* - T....T */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { - const vector_t vec(parameters[0]); + std::size_t cnt = 0; - std::size_t r0 = 0; - std::size_t r1 = vec.size() - 1; + if (2 == ps_index) + { + for (std::size_t i = 0; i < parameters.size(); ++i) + { + if (scalar_t(parameters[i])() != T(0)) ++cnt; + } + } + else + { + const vector_t vec(parameters[0]); - if ( - (1 == ps_index) && - !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) - ) - return std::numeric_limits::quiet_NaN(); + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; - std::size_t cnt = 0; + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { + return std::numeric_limits::quiet_NaN(); + } - for (std::size_t i = r0; i <= r1; ++i) - { - if (vec[i] != T(0)) ++cnt; + for (std::size_t i = r0; i <= r1; ++i) + { + if (vec[i] != T(0)) ++cnt; + } } return T(cnt); @@ -40043,7 +44734,7 @@ namespace exprtk }; template - class copy : public exprtk::igeneric_function + class copy exprtk_final : public exprtk::igeneric_function { public: @@ -40053,7 +44744,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); copy() : exprtk::igeneric_function("VV|VTTVTT") @@ -40064,7 +44755,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[0]); vector_t y(parameters[(0 == ps_index) ? 1 : 3]); @@ -40096,7 +44787,7 @@ namespace exprtk }; template - class rol : public exprtk::igeneric_function + class rol exprtk_final : public exprtk::igeneric_function { public: @@ -40106,7 +44797,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); rol() : exprtk::igeneric_function("VT|VTTT") @@ -40117,7 +44808,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { vector_t vec(parameters[0]); @@ -40147,7 +44838,7 @@ namespace exprtk }; template - class ror : public exprtk::igeneric_function + class ror exprtk_final : public exprtk::igeneric_function { public: @@ -40157,7 +44848,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); ror() : exprtk::igeneric_function("VT|VTTT") @@ -40168,7 +44859,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { vector_t vec(parameters[0]); @@ -40185,8 +44876,8 @@ namespace exprtk ) return T(0); - std::size_t dist = r1 - r0 + 1; - std::size_t shift = (dist - (n % dist)) % dist; + const std::size_t dist = r1 - r0 + 1; + const std::size_t shift = (dist - (n % dist)) % dist; std::rotate( vec.begin() + r0, @@ -40198,7 +44889,7 @@ namespace exprtk }; template - class shift_left : public exprtk::igeneric_function + class reverse exprtk_final : public exprtk::igeneric_function { public: @@ -40208,7 +44899,48 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); + + reverse() + : exprtk::igeneric_function("V|VTT") + /* + Overloads: + 0. V - vector + 1. VTT - vector, r0, r1 + */ + {} + + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override + { + vector_t vec(parameters[0]); + + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; + + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + return T(0); + + std::reverse(vec.begin() + r0, vec.begin() + r1 + 1); + + return T(1); + } + }; + + template + class shift_left exprtk_final : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using igfun_t::operator(); shift_left() : exprtk::igeneric_function("VT|VTTT") @@ -40219,7 +44951,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { vector_t vec(parameters[0]); @@ -40246,7 +44978,7 @@ namespace exprtk vec.begin() + r0 + n, vec.begin() + r1 + 1); - for (std::size_t i = r1 - n + 1; i <= r1; ++i) + for (std::size_t i = r1 - n + 1ULL; i <= r1; ++i) { vec[i] = T(0); } @@ -40256,7 +44988,7 @@ namespace exprtk }; template - class shift_right : public exprtk::igeneric_function + class shift_right exprtk_final : public exprtk::igeneric_function { public: @@ -40266,7 +44998,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); shift_right() : exprtk::igeneric_function("VT|VTTT") @@ -40277,7 +45009,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { vector_t vec(parameters[0]); @@ -40316,7 +45048,7 @@ namespace exprtk }; template - class sort : public exprtk::igeneric_function + class sort exprtk_final : public exprtk::igeneric_function { public: @@ -40326,7 +45058,7 @@ namespace exprtk typedef typename generic_type::string_view string_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); sort() : exprtk::igeneric_function("V|VTT|VS|VSTT") @@ -40339,7 +45071,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { vector_t vec(parameters[0]); @@ -40379,7 +45111,7 @@ namespace exprtk }; template - class nthelement : public exprtk::igeneric_function + class nthelement exprtk_final : public exprtk::igeneric_function { public: @@ -40389,7 +45121,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); nthelement() : exprtk::igeneric_function("VT|VTTT") @@ -40400,7 +45132,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { vector_t vec(parameters[0]); @@ -40412,7 +45144,9 @@ namespace exprtk return T(0); if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 2, 3, 0)) + { return std::numeric_limits::quiet_NaN(); + } std::nth_element( vec.begin() + r0, @@ -40424,7 +45158,7 @@ namespace exprtk }; template - class iota : public exprtk::igeneric_function + class assign exprtk_final : public exprtk::igeneric_function { public: @@ -40434,41 +45168,101 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); + + assign() + : exprtk::igeneric_function("VT|VTTT|VTTTT") + /* + Overloads: + 0. VT - vector, V + 1. VTTT - vector, V, r0, r1 + 2. VTTTT - vector, V, r0, r1, SS + */ + {} + + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override + { + vector_t vec(parameters[0]); + + const T assign_value = scalar_t(parameters[1]); + + const std::size_t step_size = (2 != ps_index) ? 1 : + static_cast(scalar_t(parameters.back())()); + + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; + + if ( + ((ps_index == 1) || (ps_index == 2)) && + !helper::load_vector_range::process(parameters, r0, r1, 2, 3, 0) + ) + { + return T(0); + } + + for (std::size_t i = r0; i <= r1; i += step_size) + { + vec[i] = assign_value; + } + + return T(1); + } + }; + + template + class iota exprtk_final : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using igfun_t::operator(); iota() - : exprtk::igeneric_function("VT|VTT|VTTT|VTTTT") + : exprtk::igeneric_function("VTT|VT|VTTTT|VTTT") /* Overloads: - 0. VT - vector, increment - 1. VTT - vector, increment, base - 2. VTTTT - vector, increment, r0, r1 - 3. VTTTT - vector, increment, base, r0, r1 + 0. VTT - vector, SV, SS + 1. VT - vector, SV, SS (+1) + 2. VTTT - vector, r0, r1, SV, SS + 3. VTT - vector, r0, r1, SV, SS (+1) + + Where: + 1. SV - Start value + 2. SS - Step size */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { vector_t vec(parameters[0]); - T increment = scalar_t(parameters[1])(); - T base = ((1 == ps_index) || (3 == ps_index)) ? scalar_t(parameters[2])() : T(0); + const T start_value = (ps_index <= 1) ? + scalar_t(parameters[1]) : + scalar_t(parameters[3]) ; + + const T step_size = ((0 == ps_index) || (2 == ps_index)) ? + scalar_t(parameters.back())() : + T(1) ; std::size_t r0 = 0; std::size_t r1 = vec.size() - 1; - if ((2 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 2, 3, 0)) - return std::numeric_limits::quiet_NaN(); - else if ((3 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 3, 4, 0)) - return std::numeric_limits::quiet_NaN(); - else + if ( + ((ps_index == 2) || (ps_index == 3)) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) { - long long j = 0; + return T(0); + } - for (std::size_t i = r0; i <= r1; ++i, ++j) - { - vec[i] = base + (increment * j); - } + for (std::size_t i = r0; i <= r1; ++i) + { + vec[i] = start_value + ((i - r0) * step_size); } return T(1); @@ -40476,40 +45270,50 @@ namespace exprtk }; template - class sumk : public exprtk::igeneric_function + class sumk exprtk_final : public exprtk::igeneric_function { public: typedef typename exprtk::igeneric_function igfun_t; typedef typename igfun_t::parameter_list_t parameter_list_t; typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); sumk() - : exprtk::igeneric_function("V|VTT") + : exprtk::igeneric_function("V|VTT|VTTT") /* Overloads: - 0. V - vector - 1. VTT - vector, r0, r1 + 0. V - vector + 1. VTT - vector, r0, r1 + 2. VTTT - vector, r0, r1, stride */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t vec(parameters[0]); + const std::size_t stride = (2 != ps_index) ? 1 : + static_cast(scalar_t(parameters[3])()); + std::size_t r0 = 0; std::size_t r1 = vec.size() - 1; - if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0)) + if ( + ((1 == ps_index) || (2 == ps_index)) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { return std::numeric_limits::quiet_NaN(); + } T result = T(0); T error = T(0); - for (std::size_t i = r0; i <= r1; ++i) + for (std::size_t i = r0; i <= r1; i += stride) { details::kahan_sum(result, error, vec[i]); } @@ -40519,7 +45323,7 @@ namespace exprtk }; template - class axpy : public exprtk::igeneric_function + class axpy exprtk_final : public exprtk::igeneric_function { public: @@ -40529,7 +45333,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); axpy() : exprtk::igeneric_function("TVV|TVVTT") @@ -40541,7 +45345,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[1]); vector_t y(parameters[2]); @@ -40566,7 +45370,7 @@ namespace exprtk }; template - class axpby : public exprtk::igeneric_function + class axpby exprtk_final : public exprtk::igeneric_function { public: @@ -40576,7 +45380,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); axpby() : exprtk::igeneric_function("TVTV|TVTVTT") @@ -40588,7 +45392,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[1]); vector_t y(parameters[3]); @@ -40614,7 +45418,7 @@ namespace exprtk }; template - class axpyz : public exprtk::igeneric_function + class axpyz exprtk_final : public exprtk::igeneric_function { public: @@ -40624,7 +45428,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); axpyz() : exprtk::igeneric_function("TVVV|TVVVTT") @@ -40636,7 +45440,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[1]); const vector_t y(parameters[2]); @@ -40645,7 +45449,7 @@ namespace exprtk std::size_t r0 = 0; std::size_t r1 = std::min(x.size(),y.size()) - 1; - if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 3, 4, 1)) + if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 4, 5, 1)) return std::numeric_limits::quiet_NaN(); else if (helper::invalid_range(y, r0, r1)) return std::numeric_limits::quiet_NaN(); @@ -40664,7 +45468,7 @@ namespace exprtk }; template - class axpbyz : public exprtk::igeneric_function + class axpbyz exprtk_final : public exprtk::igeneric_function { public: @@ -40674,7 +45478,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); axpbyz() : exprtk::igeneric_function("TVTVV|TVTVVTT") @@ -40686,7 +45490,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[1]); const vector_t y(parameters[3]); @@ -40695,7 +45499,7 @@ namespace exprtk std::size_t r0 = 0; std::size_t r1 = std::min(x.size(),y.size()) - 1; - if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 4, 5, 1)) + if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 5, 6, 1)) return std::numeric_limits::quiet_NaN(); else if (helper::invalid_range(y, r0, r1)) return std::numeric_limits::quiet_NaN(); @@ -40715,7 +45519,7 @@ namespace exprtk }; template - class axpbz : public exprtk::igeneric_function + class axpbsy exprtk_final : public exprtk::igeneric_function { public: @@ -40725,7 +45529,110 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); + + axpbsy() + : exprtk::igeneric_function("TVTTV|TVTTVTT") + /* + y <- ax + by + Overloads: + 0. TVTVV - a, x(vector), b, shift, y(vector), z(vector) + 1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1 + */ + {} + + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override + { + const vector_t x(parameters[1]); + vector_t y(parameters[4]); + + std::size_t r0 = 0; + std::size_t r1 = std::min(x.size(),y.size()) - 1; + + if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 5, 6, 1)) + return std::numeric_limits::quiet_NaN(); + else if (helper::invalid_range(y, r0, r1)) + return std::numeric_limits::quiet_NaN(); + + const T a = scalar_t(parameters[0])(); + const T b = scalar_t(parameters[2])(); + + const std::size_t s = static_cast(scalar_t(parameters[3])()); + + for (std::size_t i = r0; i <= r1; ++i) + { + y[i] = (a * x[i]) + (b * y[i + s]); + } + + return T(1); + } + }; + + template + class axpbsyz exprtk_final : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using igfun_t::operator(); + + axpbsyz() + : exprtk::igeneric_function("TVTTVV|TVTTVVTT") + /* + z <- ax + by + Overloads: + 0. TVTVV - a, x(vector), b, shift, y(vector), z(vector) + 1. TVTVVTT - a, x(vector), b, shift, y(vector), z(vector), r0, r1 + */ + {} + + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override + { + const vector_t x(parameters[1]); + const vector_t y(parameters[4]); + vector_t z(parameters[5]); + + std::size_t r0 = 0; + std::size_t r1 = std::min(x.size(),y.size()) - 1; + + if ((1 == ps_index) && !helper::load_vector_range::process(parameters, r0, r1, 6, 7, 1)) + return std::numeric_limits::quiet_NaN(); + else if (helper::invalid_range(y, r0, r1)) + return std::numeric_limits::quiet_NaN(); + else if (helper::invalid_range(z, r0, r1)) + return std::numeric_limits::quiet_NaN(); + + const T a = scalar_t(parameters[0])(); + const T b = scalar_t(parameters[2])(); + + const std::size_t s = static_cast(scalar_t(parameters[3])()); + + for (std::size_t i = r0; i <= r1; ++i) + { + z[i] = (a * x[i]) + (b * y[i + s]); + } + + return T(1); + } + }; + + template + class axpbz exprtk_final : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using igfun_t::operator(); axpbz() : exprtk::igeneric_function("TVTV|TVTVTT") @@ -40737,7 +45644,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[1]); vector_t z(parameters[3]); @@ -40763,7 +45670,7 @@ namespace exprtk }; template - class dot : public exprtk::igeneric_function + class diff exprtk_final : public exprtk::igeneric_function { public: @@ -40773,7 +45680,55 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); + + diff() + : exprtk::igeneric_function("VV|VVT") + /* + x_(i - stride) - x_i + Overloads: + 0. VV - x(vector), y(vector) + 1. VVT - x(vector), y(vector), stride + */ + {} + + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override + { + const vector_t x(parameters[0]); + vector_t y(parameters[1]); + + const std::size_t r0 = 0; + const std::size_t r1 = std::min(x.size(),y.size()) - 1; + + const std::size_t stride = (1 != ps_index) ? 1 : + std::min(r1,static_cast(scalar_t(parameters[2])())); + + for (std::size_t i = 0; i < stride; ++i) + { + y[i] = std::numeric_limits::quiet_NaN(); + } + + for (std::size_t i = (r0 + stride); i <= r1; ++i) + { + y[i] = x[i] - x[i - stride]; + } + + return T(1); + } + }; + + template + class dot exprtk_final : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using igfun_t::operator(); dot() : exprtk::igeneric_function("VV|VVTT") @@ -40784,7 +45739,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[0]); const vector_t y(parameters[1]); @@ -40809,7 +45764,7 @@ namespace exprtk }; template - class dotk : public exprtk::igeneric_function + class dotk exprtk_final : public exprtk::igeneric_function { public: @@ -40819,7 +45774,7 @@ namespace exprtk typedef typename generic_type::scalar_view scalar_t; typedef typename generic_type::vector_view vector_t; - using exprtk::igeneric_function::operator(); + using igfun_t::operator(); dotk() : exprtk::igeneric_function("VV|VVTT") @@ -40830,7 +45785,7 @@ namespace exprtk */ {} - inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override { const vector_t x(parameters[0]); const vector_t y(parameters[1]); @@ -40855,30 +45810,155 @@ namespace exprtk } }; + template + class threshold_below exprtk_final : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using igfun_t::operator(); + + threshold_below() + : exprtk::igeneric_function("VTT|VTTTT") + /* + Overloads: + 0. VTT - vector, TV, SV + 1. VTTTT - vector, r0, r1, TV, SV + + Where: + TV - Threshold value + SV - Snap-to value + */ + {} + + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override + { + vector_t vec(parameters[0]); + + const T threshold_value = (0 == ps_index) ? + scalar_t(parameters[1]) : + scalar_t(parameters[3]) ; + + const T snap_value = scalar_t(parameters.back()); + + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; + + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { + return T(0); + } + + for (std::size_t i = r0; i <= r1; ++i) + { + if (vec[i] < threshold_value) + { + vec[i] = snap_value; + } + } + + return T(1); + } + }; + + template + class threshold_above exprtk_final : public exprtk::igeneric_function + { + public: + + typedef typename exprtk::igeneric_function igfun_t; + typedef typename igfun_t::parameter_list_t parameter_list_t; + typedef typename igfun_t::generic_type generic_type; + typedef typename generic_type::scalar_view scalar_t; + typedef typename generic_type::vector_view vector_t; + + using igfun_t::operator(); + + threshold_above() + : exprtk::igeneric_function("VTT|VTTTT") + /* + Overloads: + 0. VTT - vector, TV, SV + 1. VTTTT - vector, r0, r1, TV, SV + + Where: + TV - Threshold value + SV - Snap-to value + */ + {} + + inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) exprtk_override + { + vector_t vec(parameters[0]); + + const T threshold_value = (0 == ps_index) ? + scalar_t(parameters[1]) : + scalar_t(parameters[3]) ; + + const T snap_value = scalar_t(parameters.back()); + + std::size_t r0 = 0; + std::size_t r1 = vec.size() - 1; + + if ( + (1 == ps_index) && + !helper::load_vector_range::process(parameters, r0, r1, 1, 2, 0) + ) + { + return T(0); + } + + for (std::size_t i = r0; i <= r1; ++i) + { + if (vec[i] > threshold_value) + { + vec[i] = snap_value; + } + } + + return T(1); + } + }; + template struct package { - all_true at; - all_false af; - any_true nt; - any_false nf; - count c; - copy cp; - rol rl; - ror rr; - shift_left sl; - shift_right sr; - sort st; - nthelement ne; - iota ia; - sumk sk; - axpy b1_axpy; - axpby b1_axpby; - axpyz b1_axpyz; - axpbyz b1_axpbyz; - axpbz b1_axpbz; - dot dt; - dotk dtk; + all_true at; + all_false af; + any_true nt; + any_false nf; + count c; + copy cp; + rol rl; + ror rr; + reverse rev; + shift_left sl; + shift_right sr; + sort st; + nthelement ne; + assign an; + iota ia; + sumk sk; + axpy b1_axpy; + axpby b1_axpby; + axpyz b1_axpyz; + axpbyz b1_axpbyz; + axpbsy b1_axpbsy; + axpbsyz b1_axpbsyz; + axpbz b1_axpbz; + diff df; + dot dt; + dotk dtk; + threshold_above ta; + threshold_below tb; bool register_package(exprtk::symbol_table& symtab) { @@ -40891,29 +45971,36 @@ namespace exprtk return false; \ } \ - exprtk_register_function("all_true" , at ) - exprtk_register_function("all_false" , af ) - exprtk_register_function("any_true" , nt ) - exprtk_register_function("any_false" , nf ) - exprtk_register_function("count" , c ) - exprtk_register_function("copy" , cp ) - exprtk_register_function("rotate_left" , rl ) - exprtk_register_function("rol" , rl ) - exprtk_register_function("rotate_right" , rr ) - exprtk_register_function("ror" , rr ) - exprtk_register_function("shftl" , sl ) - exprtk_register_function("shftr" , sr ) - exprtk_register_function("sort" , st ) - exprtk_register_function("nth_element" , ne ) - exprtk_register_function("iota" , ia ) - exprtk_register_function("sumk" , sk ) - exprtk_register_function("axpy" , b1_axpy ) - exprtk_register_function("axpby" , b1_axpby ) - exprtk_register_function("axpyz" , b1_axpyz ) - exprtk_register_function("axpbyz" , b1_axpbyz) - exprtk_register_function("axpbz" , b1_axpbz ) - exprtk_register_function("dot" , dt ) - exprtk_register_function("dotk" , dtk ) + exprtk_register_function("all_true" , at ) + exprtk_register_function("all_false" , af ) + exprtk_register_function("any_true" , nt ) + exprtk_register_function("any_false" , nf ) + exprtk_register_function("count" , c ) + exprtk_register_function("copy" , cp ) + exprtk_register_function("rotate_left" , rl ) + exprtk_register_function("rol" , rl ) + exprtk_register_function("rotate_right" , rr ) + exprtk_register_function("ror" , rr ) + exprtk_register_function("reverse" , rev ) + exprtk_register_function("shftl" , sl ) + exprtk_register_function("shftr" , sr ) + exprtk_register_function("sort" , st ) + exprtk_register_function("nth_element" , ne ) + exprtk_register_function("assign" , an ) + exprtk_register_function("iota" , ia ) + exprtk_register_function("sumk" , sk ) + exprtk_register_function("axpy" , b1_axpy ) + exprtk_register_function("axpby" , b1_axpby ) + exprtk_register_function("axpyz" , b1_axpyz ) + exprtk_register_function("axpbyz" , b1_axpbyz ) + exprtk_register_function("axpbsy" , b1_axpbsy ) + exprtk_register_function("axpbsyz" , b1_axpbsyz) + exprtk_register_function("axpbz" , b1_axpbz ) + exprtk_register_function("diff" , df ) + exprtk_register_function("dot" , dt ) + exprtk_register_function("dotk" , dtk ) + exprtk_register_function("threshold_above" , ta ) + exprtk_register_function("threshold_below" , tb ) #undef exprtk_register_function return true; @@ -40932,11 +46019,11 @@ namespace exprtk using ::exprtk::details::char_cptr; static char_cptr library = "Mathematical Expression Toolkit"; - static char_cptr version = "2.71828182845904523536028747135266" - "2497757247093699959574966967627724" - "0766303535475945713821785251664274" - "2746639193200305992181741359662904"; - static char_cptr date = "20230101"; + static char_cptr version = "2.718281828459045235360287471352662497757" + "24709369995957496696762772407663035354759" + "45713821785251664274274663919320030599218" + "17413596629043572900334295260595630738132"; + static char_cptr date = "20240101"; static char_cptr min_cpp = "199711L"; static inline std::string data() @@ -40958,12 +46045,8 @@ namespace exprtk #undef exprtk_error_location #endif - #ifdef exprtk_disable_fallthrough_begin - #undef exprtk_disable_fallthrough_begin - #endif - - #ifdef exprtk_disable_fallthrough_end - #undef exprtk_disable_fallthrough_end + #ifdef exprtk_fallthrough + #undef exprtk_fallthrough #endif #ifdef exprtk_override From d96e711a34ce621b5a37e0506e8b315f0a5bf10a Mon Sep 17 00:00:00 2001 From: cppla Date: Fri, 19 Jan 2024 16:03:43 +0800 Subject: [PATCH 020/134] change ms and lost rate --- web/js/serverstatus.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/js/serverstatus.js b/web/js/serverstatus.js index ce3a6923..43c12375 100644 --- a/web/js/serverstatus.js +++ b/web/js/serverstatus.js @@ -82,7 +82,6 @@ function uptime() { "
加载中
" + "
加载中
" + "
加载中
" + - "
加载中
" + "
加载中
" + "" ); @@ -255,13 +254,14 @@ function uptime() { // tcp, udp, process, thread count ExpandRow[0].children["expand_tupd"].innerHTML = "TCP/UDP/进/线: " + result.servers[i].tcp_count + " / " + result.servers[i].udp_count + " / " + result.servers[i].process_count+ " / " + result.servers[i].thread_count; - ExpandRow[0].children["expand_ping"].innerHTML = "联通/电信/移动: " + result.servers[i].time_10010 + "ms / " + result.servers[i].time_189 + "ms / " + result.servers[i].time_10086 + "ms" // ping var PING_10010 = result.servers[i].ping_10010.toFixed(0); var PING_189 = result.servers[i].ping_189.toFixed(0); var PING_10086 = result.servers[i].ping_10086.toFixed(0); - ExpandRow[0].children["expand_lost"].innerHTML = "丢包:联通/电信/移动: " + PING_10010 + "% / " + PING_189 + "% / " + PING_10086 + "%" + + // ping ms + lost rate + ExpandRow[0].children["expand_ping"].innerHTML = "CU/CT/CM: " + result.servers[i].time_10010 + "ms ("+result.servers[i].ping_10010.toFixed(0)+"%) / " + result.servers[i].time_189 + "ms ("+result.servers[i].ping_189.toFixed(0)+"%) / " + result.servers[i].time_10086 + "ms ("+result.servers[i].ping_10086.toFixed(0)+"%)" if (PING_10010 >= 20 || PING_189 >= 20 || PING_10086 >= 20) TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-danger"; From 71cadcfebe05d97fb609b2b380ff82213f01faa0 Mon Sep 17 00:00:00 2001 From: cppla Date: Sun, 21 Jan 2024 21:09:37 +0800 Subject: [PATCH 021/134] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E9=87=8D=E8=A6=81=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/client-linux.py | 118 +++++++++++++++++++++++++++++++++++++-- clients/client-psutil.py | 118 +++++++++++++++++++++++++++++++++++++-- server/config.json | 40 +++++++++---- server/src/main.cpp | 34 +++++++++++ server/src/main.h | 11 +++- web/css/dark.css | 66 +++++++++------------- web/css/light.css | 66 +++++++++------------- web/index.html | 73 ++++++++++++++++-------- web/js/serverstatus.js | 42 +++++++++++--- 9 files changed, 434 insertions(+), 134 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 00e59d5c..05744530 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -20,6 +20,7 @@ INTERVAL = 1 import socket +import ssl import time import timeit import re @@ -29,10 +30,10 @@ import errno import subprocess import threading -try: - from queue import Queue # python3 -except ImportError: - from Queue import Queue # python2 +if sys.version_info.major == 3: + from queue import Queue +elif sys.version_info.major == 2: + from Queue import Queue def get_uptime(): with open('/proc/uptime', 'r') as f: @@ -150,6 +151,7 @@ def get_network(ip_version): 'read': 0, 'write': 0 } +monitorServer = {} def _ping_thread(host, mark, port): lostPacket = 0 @@ -314,6 +316,97 @@ def get_realtime_data(): ti.daemon = True ti.start() + +def _monitor_thread(name, host, interval, type): + lostPacket = 0 + packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN) + while True: + if name not in monitorServer.keys(): + monitorServer[name] = { + "type": type, + "dns_time": 0, + "connect_time": 0, + "download_time": 0, + "online_rate": 1 + } + if packet_queue.full(): + if packet_queue.get() == 0: + lostPacket -= 1 + try: + if type == "http": + address = host.replace("http://", "") + m = timeit.default_timer() + if PROBE_PROTOCOL_PREFER == 'ipv4': + IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0] + else: + IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0] + monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k = socket.create_connection((IP, 80), timeout=6) + monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + response = b"" + while True: + data = k.recv(4096) + if not data: + break + response += data + http_code = response.decode('utf-8').split('\r\n')[0].split()[1] + monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000) + k.close() + if http_code not in ['200', '204', '301', '302', '401']: + raise Exception("http code not in 200, 204, 301, 302, 401") + elif type == "https": + context = ssl._create_unverified_context() + address = host.replace("https://", "") + m = timeit.default_timer() + if PROBE_PROTOCOL_PREFER == 'ipv4': + IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0] + else: + IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0] + monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k = socket.create_connection((IP, 443), timeout=6) + monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + kk = context.wrap_socket(k, server_hostname=address) + kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + response = b"" + while True: + data = kk.recv(4096) + if not data: + break + response += data + http_code = response.decode('utf-8').split('\r\n')[0].split()[1] + monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000) + kk.close() + k.close() + if http_code not in ['200', '204', '301', '302', '401']: + raise Exception("http code not in 200, 204, 301, 302, 401") + elif type == "tcp": + m = timeit.default_timer() + if PROBE_PROTOCOL_PREFER == 'ipv4': + IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET)[0][4][0] + else: + IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET6)[0][4][0] + monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k = socket.create_connection((IP, int(host.split(":")[1])), timeout=6) + monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k.send(b"GET / HTTP/1.2\r\n\r\n") + k.recv(1024) + monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000) + k.close() + packet_queue.put(1) + except Exception as e: + lostPacket += 1 + packet_queue.put(0) + if packet_queue.qsize() > 5: + monitorServer[name]["online_rate"] = 1 - float(lostPacket) / packet_queue.qsize() + time.sleep(interval) + def byte_str(object): ''' bytes to str, str to bytes @@ -360,6 +453,20 @@ def byte_str(object): if data.find("You are connecting via") < 0: data = byte_str(s.recv(1024)) print(data) + for i in data.split('\n'): + if "monitor" in i and "type" in i and "{" in i and "}" in i: + jdata = json.loads(i[i.find("{"):i.find("}")+1]) + t = threading.Thread( + target=_monitor_thread, + kwargs={ + 'name': jdata.get("name"), + 'host': jdata.get("host"), + 'interval': jdata.get("interval"), + 'type': jdata.get("type") + } + ) + t.daemon = True + t.start() timer = 0 check_ip = 0 @@ -378,7 +485,6 @@ def byte_str(object): Load_1, Load_5, Load_15 = os.getloadavg() MemoryTotal, MemoryUsed, SwapTotal, SwapFree = get_memory() HDDTotal, HDDUsed = get_hdd() - array = {} if not timer: array['online' + str(check_ip)] = get_network(check_ip) @@ -412,7 +518,7 @@ def byte_str(object): array['tcp'], array['udp'], array['process'], array['thread'] = tupd() array['io_read'] = diskIO.get("read") array['io_write'] = diskIO.get("write") - + array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100}%" for k, v in monitorServer.items()) s.send(byte_str("update " + json.dumps(array) + "\n")) except KeyboardInterrupt: raise diff --git a/clients/client-psutil.py b/clients/client-psutil.py index ceac788a..c2b39281 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -21,6 +21,7 @@ INTERVAL = 1 import socket +import ssl import time import timeit import os @@ -29,10 +30,10 @@ import errno import psutil import threading -try: - from queue import Queue # python3 -except ImportError: - from Queue import Queue # python2 +if sys.version_info.major == 3: + from queue import Queue +elif sys.version_info.major == 2: + from Queue import Queue def get_uptime(): return int(time.time() - psutil.boot_time()) @@ -148,6 +149,7 @@ def get_network(ip_version): 'read': 0, 'write': 0 } +monitorServer = {} def _ping_thread(host, mark, port): lostPacket = 0 @@ -303,6 +305,97 @@ def get_realtime_data(): ti.daemon = True ti.start() +def _monitor_thread(name, host, interval, type): + lostPacket = 0 + packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN) + while True: + if name not in monitorServer.keys(): + monitorServer[name] = { + "type": type, + "dns_time": 0, + "connect_time": 0, + "download_time": 0, + "online_rate": 1 + } + if packet_queue.full(): + if packet_queue.get() == 0: + lostPacket -= 1 + try: + if type == "http": + address = host.replace("http://", "") + m = timeit.default_timer() + if PROBE_PROTOCOL_PREFER == 'ipv4': + IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0] + else: + IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0] + monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k = socket.create_connection((IP, 80), timeout=6) + monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + response = b"" + while True: + data = k.recv(4096) + if not data: + break + response += data + http_code = response.decode('utf-8').split('\r\n')[0].split()[1] + monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000) + k.close() + if http_code not in ['200', '204', '301', '302', '401']: + raise Exception("http code not in 200, 204, 301, 302, 401") + elif type == "https": + context = ssl._create_unverified_context() + address = host.replace("https://", "") + m = timeit.default_timer() + if PROBE_PROTOCOL_PREFER == 'ipv4': + IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0] + else: + IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0] + monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k = socket.create_connection((IP, 443), timeout=6) + monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + kk = context.wrap_socket(k, server_hostname=address) + kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + response = b"" + while True: + data = kk.recv(4096) + if not data: + break + response += data + http_code = response.decode('utf-8').split('\r\n')[0].split()[1] + monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000) + kk.close() + k.close() + if http_code not in ['200', '204', '301', '302', '401']: + raise Exception("http code not in 200, 204, 301, 302, 401") + elif type == "tcp": + m = timeit.default_timer() + if PROBE_PROTOCOL_PREFER == 'ipv4': + IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET)[0][4][0] + else: + IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET6)[0][4][0] + monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k = socket.create_connection((IP, int(host.split(":")[1])), timeout=6) + monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) + m = timeit.default_timer() + k.send(b"GET / HTTP/1.2\r\n\r\n") + k.recv(1024) + monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000) + k.close() + packet_queue.put(1) + except Exception as e: + lostPacket += 1 + packet_queue.put(0) + if packet_queue.qsize() > 5: + monitorServer[name]["online_rate"] = 1 - float(lostPacket) / packet_queue.qsize() + time.sleep(interval) + + def byte_str(object): ''' bytes to str, str to bytes @@ -349,6 +442,20 @@ def byte_str(object): if data.find("You are connecting via") < 0: data = byte_str(s.recv(1024)) print(data) + for i in data.split('\n'): + if "monitor" in i and "type" in i and "{" in i and "}" in i: + jdata = json.loads(i[i.find("{"):i.find("}")+1]) + t = threading.Thread( + target=_monitor_thread, + kwargs={ + 'name': jdata.get("name"), + 'host': jdata.get("host"), + 'interval': jdata.get("interval"), + 'type': jdata.get("type") + } + ) + t.daemon = True + t.start() timer = 0 check_ip = 0 @@ -368,7 +475,6 @@ def byte_str(object): MemoryTotal, MemoryUsed = get_memory() SwapTotal, SwapUsed = get_swap() HDDTotal, HDDUsed = get_hdd() - array = {} if not timer: array['online' + str(check_ip)] = get_network(check_ip) @@ -402,7 +508,7 @@ def byte_str(object): array['tcp'], array['udp'], array['process'], array['thread'] = tupd() array['io_read'] = diskIO.get("read") array['io_write'] = diskIO.get("write") - + array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100}%" for k, v in monitorServer.items()) s.send(byte_str("update " + json.dumps(array) + "\n")) except KeyboardInterrupt: raise diff --git a/server/config.json b/server/config.json index c60018ff..29a4df47 100644 --- a/server/config.json +++ b/server/config.json @@ -38,6 +38,26 @@ "monthstart": 1 } ], + "monitors": [ + { + "name": "百度一下", + "host": "https://www.baidu.com", + "interval": 60, + "type": "https" + }, + { + "name": "主机交流", + "host": "https://www.hostloc.com", + "interval": 60, + "type": "https" + }, + { + "name": "DNS服务", + "host": "114.114.114.114:53", + "interval": 60, + "type": "tcp" + } + ], "watchdog": [ { "name": "cpu high warning,exclude username s01", @@ -58,17 +78,17 @@ "callback": "https://yourSMSurl" }, { - "name": "ddcc attack,limit type Oracle", - "rule": "tcp_count>600&type='Oracle'", - "interval": 300, - "callback": "https://yourSMSurl" - }, + "name": "ddcc attack,limit type Oracle", + "rule": "tcp_count>600&type='Oracle'", + "interval": 300, + "callback": "https://yourSMSurl" + }, { - "name": "month traffic warning", - "rule": "(network_out-last_network_out)/1024/1024/1024>999", - "interval": 3600, - "callback": "https://yourSMSurl" - }, + "name": "month traffic warning", + "rule": "(network_out-last_network_out)/1024/1024/1024>999", + "interval": 3600, + "callback": "https://yourSMSurl" + }, { "name": "you can parse an expression combining any known field", "rule": "load_5>3", diff --git a/server/src/main.cpp b/server/src/main.cpp index d24d6057..2dc5c434 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -92,6 +92,18 @@ void CMain::OnNewClient(int ClientNetID, int ClientID) Client(ClientID)->m_Stats.m_Online4 = true; else if(Client(ClientID)->m_ClientNetType == NETTYPE_IPV6) Client(ClientID)->m_Stats.m_Online6 = true; + + // Send monitor to client + // support by cpp.la + int ID = 0; + char monitorBuffer[2048]; + while (strcmp(Monitors(ID)->m_aName, "NULL")) + { + memset(monitorBuffer, 0, sizeof(monitorBuffer)); + sprintf(monitorBuffer, "{\"name\":\"%s\",\"host\":\"%s\",\"interval\":%d,\"type\":\"%s\",\"monitor\":%d}", Monitors(ID)->m_aName, Monitors(ID)->m_aHost, Monitors(ID)->m_aInterval, Monitors(ID)->m_aType, ID); + m_Server.Network()->Send(ClientNetID, monitorBuffer); + ID++; + } } void CMain::OnDelClient(int ClientNetID) @@ -572,6 +584,28 @@ int CMain::ReadConfig() } else str_copy(Watchdog(ID)->m_aName, "NULL", sizeof(Watchdog(ID)->m_aName)); + // monitor + // support by: https://cpp.la + ID = 0; + const json_value &mStart = (*pJsonData)["monitors"]; + if(mStart.type == json_array) + { + for(unsigned i = 0; i < mStart.u.array.length; i++) + { + if(ID < 0 || ID >= NET_MAX_CLIENTS) + continue; + + str_copy(Monitors(ID)->m_aName, mStart[i]["name"].u.string.ptr, sizeof(Monitors(ID)->m_aName)); + str_copy(Monitors(ID)->m_aHost, mStart[i]["host"].u.string.ptr, sizeof(Monitors(ID)->m_aHost)); + Monitors(ID)->m_aInterval = mStart[i]["interval"].u.integer; + str_copy(Monitors(ID)->m_aType, mStart[i]["type"].u.string.ptr, sizeof(Monitors(ID)->m_aType)); + + ID++; + } + str_copy(Monitors(ID)->m_aName, "NULL", sizeof(Monitors(ID)->m_aName)); + } else + str_copy(Monitors(ID)->m_aName, "NULL", sizeof(Monitors(ID)->m_aName)); + // if file exists, read last network traffic record,reset m_LastNetworkIN and m_LastNetworkOUT // support by: https://cpp.la IOHANDLE nFile = io_open(m_Config.m_aJSONFile, IOFLAG_READ); diff --git a/server/src/main.h b/server/src/main.h index eb3fb3ef..848d2468 100644 --- a/server/src/main.h +++ b/server/src/main.h @@ -77,7 +77,7 @@ class CMain int64_t m_IORead; int64_t m_IOWrite; double m_CPU; - char m_aCustom[512]; + char m_aCustom[1024]; // Options bool m_Pong; } m_Stats; @@ -90,6 +90,13 @@ class CMain char m_aCallback[1024]; } m_aCWatchDogs[NET_MAX_CLIENTS]; + struct CMonitors{ + char m_aName[128]; + char m_aHost[128]; + int m_aInterval; + char m_aType[128]; + } m_aCMonitors[NET_MAX_CLIENTS]; + struct CJSONUpdateThreadData { CClient *pClients; @@ -108,6 +115,8 @@ class CMain int Run(); CWatchDog *Watchdog(int ruleID) { return &m_aCWatchDogs[ruleID]; } + CMonitors *Monitors(int ruleID) { return &m_aCMonitors[ruleID]; } + void WatchdogMessage(int ClientNetID, double load_1, double load_5, double load_15, double ping_10010, double ping_189, double ping_10086, double time_10010, double time_189, double time_10086, double tcp_count, double udp_count, double process_count, double thread_count, diff --git a/web/css/dark.css b/web/css/dark.css index 5bfb9491..eea98f36 100644 --- a/web/css/dark.css +++ b/web/css/dark.css @@ -23,48 +23,32 @@ tr.odd.expandRow > :hover { background: #212e36 !important; } #ping { max-width: 110px; } @media only screen and (max-width: 1200px) { - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + #server { + #type, tr td:nth-child(4) { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + } } @media only screen and (max-width: 720px) { - body { font-size: 10px; } - .content { padding: 0; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + #server { + body { font-size: 10px; } + .content { padding: 0; } + #type, tr td:nth-child(4) { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + } } @media only screen and (max-width: 620px) { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } -} -@media only screen and (max-width: 533px) { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } -} -@media only screen and (max-width: 450px) { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #name, tr td:nth-child(3) { min-width: 55px; max-width: 85px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #cpu, #ram, #hdd { min-width: 25px; max-width: 50px; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } -} + #server { + body { font-size: 10px; } + .content { padding: 0; } + #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } + #type, tr td:nth-child(4) { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + } +} \ No newline at end of file diff --git a/web/css/light.css b/web/css/light.css index e881dcb5..37e7f775 100644 --- a/web/css/light.css +++ b/web/css/light.css @@ -20,48 +20,32 @@ tr.odd.expandRow > :hover { background: #FFF !important; } #ping { max-width: 110px; } @media only screen and (max-width: 1200px) { - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + #server { + #type, tr td:nth-child(4) { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + } } @media only screen and (max-width: 720px) { - body { font-size: 10px; } - .content { padding: 0; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + #server { + body { font-size: 10px; } + .content { padding: 0; } + #type, tr td:nth-child(4) { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + } } @media only screen and (max-width: 620px) { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } -} -@media only screen and (max-width: 533px) { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } -} -@media only screen and (max-width: 450px) { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #name, tr td:nth-child(3) { min-width: 55px; max-width: 85px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #cpu, #ram, #hdd { min-width: 25px; max-width: 50px; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } -} + #server { + body { font-size: 10px; } + .content { padding: 0; } + #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } + #type, tr td:nth-child(4) { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } + } +} \ No newline at end of file diff --git a/web/index.html b/web/index.html index ed68d630..5fa61757 100644 --- a/web/index.html +++ b/web/index.html @@ -47,6 +47,12 @@

- - - - - - - - - - - - - - - - - - - - - -
🔗协议📊月流量↓|↑📌节点🗂️虚拟化🌍位置⏱️在线负载🚦网络↓|↑📋总流量↓|↑🎯核芯⚡️内存💾硬盘🌐CU|CT|CM
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
🔗协议📊月流量↓|↑📌节点🗂️虚拟化🌍位置⏱️在线负载🚦网络↓|↑📋总流量↓|↑🎯核芯⚡️内存💾硬盘🌐CU|CT|CM
+
+
+ + + + + + + + + + + + + +
🔗协议📌监测节点🌍监测位置📋监测内容
+
+
+
Updating...
diff --git a/web/js/serverstatus.js b/web/js/serverstatus.js index 43c12375..529456c0 100644 --- a/web/js/serverstatus.js +++ b/web/js/serverstatus.js @@ -57,6 +57,7 @@ function uptime() { for (var i = 0, rlen=result.servers.length; i < rlen; i++) { var TableRow = $("#servers tr#r" + i); + var MableRow = $("#monitors tr#r" + i); var ExpandRow = $("#servers #rt" + i); var hack; // fuck CSS for making me do this if(i%2) hack="odd"; else hack="even"; @@ -82,16 +83,28 @@ function uptime() { "
加载中
" + "
加载中
" + "
加载中
" + - "
加载中
" + "" ); TableRow = $("#servers tr#r" + i); ExpandRow = $("#servers #rt" + i); server_status[i] = true; } + if (!MableRow.length) { + $("#monitors").append( + "" + + "
加载中
" + + "加载中" + + "加载中" + + "加载中" + + "" + ); + MableRow = $("#monitors tr#r" + i); + } TableRow = TableRow[0]; + MableRow = MableRow[0]; if(error) { TableRow.setAttribute("data-target", "#rt" + i); + MableRow.setAttribute("data-target", "#rt" + i); server_status[i] = true; } @@ -99,25 +112,35 @@ function uptime() { if (result.servers[i].online4 && !result.servers[i].online6) { TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success"; TableRow.children["online_status"].children[0].children[0].innerHTML = "IPv4"; + MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success"; + MableRow.children["monitor_status"].children[0].children[0].innerHTML = "IPv4"; } else if (result.servers[i].online4 && result.servers[i].online6) { TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success"; TableRow.children["online_status"].children[0].children[0].innerHTML = "双栈"; + MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success"; + MableRow.children["monitor_status"].children[0].children[0].innerHTML = "双栈"; } else if (!result.servers[i].online4 && result.servers[i].online6) { TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success"; TableRow.children["online_status"].children[0].children[0].innerHTML = "IPv6"; + MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success"; + MableRow.children["monitor_status"].children[0].children[0].innerHTML = "IPv6"; } else { TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-danger"; TableRow.children["online_status"].children[0].children[0].innerHTML = "关闭"; + MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-danger"; + MableRow.children["monitor_status"].children[0].children[0].innerHTML = "关闭"; } // Name TableRow.children["name"].innerHTML = result.servers[i].name; + MableRow.children["monitor_node"].innerHTML = result.servers[i].name; // Type TableRow.children["type"].innerHTML = result.servers[i].type; // Location TableRow.children["location"].innerHTML = result.servers[i].location; + MableRow.children["monitor_location"].innerHTML = result.servers[i].location; if (!result.servers[i].online4 && !result.servers[i].online6) { if (server_status[i]) { TableRow.children["uptime"].innerHTML = "–"; @@ -138,15 +161,18 @@ function uptime() { TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-danger"; TableRow.children["ping"].children[0].children[0].style.width = "100%"; TableRow.children["ping"].children[0].children[0].innerHTML = "关闭"; + MableRow.children["monitor_text"].innerHTML = "-"; if(ExpandRow.hasClass("in")) { ExpandRow.collapse("hide"); } TableRow.setAttribute("data-target", ""); + MableRow.setAttribute("data-target", ""); server_status[i] = false; } } else { if (!server_status[i]) { TableRow.setAttribute("data-target", "#rt" + i); + MableRow.setAttribute("data-target", "#rt" + i); server_status[i] = true; } @@ -271,12 +297,8 @@ function uptime() { TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-success"; TableRow.children["ping"].children[0].children[0].innerHTML = PING_10010 + "%💻" + PING_189 + "%💻" + PING_10086 + "%"; - // Custom - if (result.servers[i].custom) { - ExpandRow[0].children["expand_custom"].innerHTML = result.servers[i].custom - } else { - ExpandRow[0].children["expand_custom"].innerHTML = "" - } + // monitor + MableRow.children["monitor_text"].innerHTML = result.servers[i].custom; } }; @@ -286,9 +308,12 @@ function uptime() { if (!error) { $("#servers > tr.accordion-toggle").each(function(i) { var TableRow = $("#servers tr#r" + i)[0]; + var MableRow = $("#monitors tr#r" + i)[0]; var ExpandRow = $("#servers #rt" + i); TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-error"; TableRow.children["online_status"].children[0].children[0].innerHTML = "错误"; + MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-error"; + MableRow.children["monitor_status"].children[0].children[0].innerHTML = "错误"; TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-error"; TableRow.children["month_traffic"].children[0].children[0].innerHTML = "错误"; TableRow.children["uptime"].children[0].children[0].className = "progress-bar progress-bar-error"; @@ -311,10 +336,13 @@ function uptime() { TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-error"; TableRow.children["ping"].children[0].children[0].style.width = "100%"; TableRow.children["ping"].children[0].children[0].innerHTML = "错误"; + MableRow.children["monitor_text"].children[0].children[0].className = "progress-bar progress-bar-error"; + MableRow.children["monitor_text"].children[0].children[0].innerHTML = "错误"; if(ExpandRow.hasClass("in")) { ExpandRow.collapse("hide"); } TableRow.setAttribute("data-target", ""); + MableRow.setAttribute("data-target", ""); server_status[i] = false; }); } From 7e46b1062e49225a324726a3a9c3cac600430b8f Mon Sep 17 00:00:00 2001 From: cppla Date: Sun, 21 Jan 2024 21:34:07 +0800 Subject: [PATCH 022/134] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=EF=BC=8C=E6=AF=94=E8=BE=83=E7=B2=97=E7=B3=99=E4=B8=8D=E5=BB=BA?= =?UTF-8?q?=E8=AE=AE=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/client-linux.py | 4 +++- clients/client-psutil.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 05744530..4d79bed1 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -3,6 +3,7 @@ # Update by : https://github.com/cppla/ServerStatus, Update date: 20220530 # 版本:1.0.3, 支持Python版本:2.7 to 3.10 # 支持操作系统: Linux, OSX, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures +# ONLINE_PACKET_HISTORY_LEN, 探测间隔60s,记录24小时在线率(1440);探测间隔60s,记录7天(10080);探测时间30s,记录24小时(2880) # 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义,例如:CU = "www.facebook.com"。 SERVER = "127.0.0.1" @@ -17,6 +18,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 +ONLINE_PACKET_HISTORY_LEN = 1440 INTERVAL = 1 import socket @@ -319,7 +321,7 @@ def get_realtime_data(): def _monitor_thread(name, host, interval, type): lostPacket = 0 - packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN) + packet_queue = Queue(maxsize=ONLINE_PACKET_HISTORY_LEN) while True: if name not in monitorServer.keys(): monitorServer[name] = { diff --git a/clients/client-psutil.py b/clients/client-psutil.py index c2b39281..d468fcbd 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -4,6 +4,7 @@ # 依赖于psutil跨平台库 # 版本:1.0.3, 支持Python版本:2.7 to 3.10 # 支持操作系统: Linux, Windows, OSX, Sun Solaris, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures +# ONLINE_PACKET_HISTORY_LEN, 探测间隔60s,记录24小时在线率(1440);探测时间60s,记录7天在线率(10080);探测时间30s,记录24小时(2880) # 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义,例如:CU = "www.facebook.com"。 SERVER = "127.0.0.1" @@ -18,6 +19,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 +ONLINE_PACKET_HISTORY_LEN = 1440 INTERVAL = 1 import socket @@ -307,7 +309,7 @@ def get_realtime_data(): def _monitor_thread(name, host, interval, type): lostPacket = 0 - packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN) + packet_queue = Queue(maxsize=ONLINE_PACKET_HISTORY_LEN) while True: if name not in monitorServer.keys(): monitorServer[name] = { From 144987bcf119e5c6c462b9cd55e462cec0bbd259 Mon Sep 17 00:00:00 2001 From: cppla Date: Sun, 21 Jan 2024 22:55:07 +0800 Subject: [PATCH 023/134] .2f --- clients/client-linux.py | 2 +- clients/client-psutil.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 4d79bed1..9f3e3151 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -520,7 +520,7 @@ def byte_str(object): array['tcp'], array['udp'], array['process'], array['thread'] = tupd() array['io_read'] = diskIO.get("read") array['io_write'] = diskIO.get("write") - array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100}%" for k, v in monitorServer.items()) + array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100:.2f}%" for k, v in monitorServer.items()) s.send(byte_str("update " + json.dumps(array) + "\n")) except KeyboardInterrupt: raise diff --git a/clients/client-psutil.py b/clients/client-psutil.py index d468fcbd..4e9c1f6f 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -510,7 +510,7 @@ def byte_str(object): array['tcp'], array['udp'], array['process'], array['thread'] = tupd() array['io_read'] = diskIO.get("read") array['io_write'] = diskIO.get("write") - array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100}%" for k, v in monitorServer.items()) + array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100:.2f}%" for k, v in monitorServer.items()) s.send(byte_str("update " + json.dumps(array) + "\n")) except KeyboardInterrupt: raise From 94708c588cab6ec3cb18df78b7d70220b5f7091c Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 22 Jan 2024 15:21:06 +0800 Subject: [PATCH 024/134] css resize --- web/css/dark.css | 44 +++++++++++++++++++------------------------- web/css/light.css | 44 +++++++++++++++++++------------------------- 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/web/css/dark.css b/web/css/dark.css index eea98f36..0d6881c9 100644 --- a/web/css/dark.css +++ b/web/css/dark.css @@ -20,35 +20,29 @@ tr.odd.expandRow > :hover { background: #212e36 !important; } #month_traffic { min-width: 85px; max-width: 95px;} #network { min-width: 110px; } #cpu, #ram, #hdd { min-width: 45px; max-width: 90px; } -#ping { max-width: 110px; } +#ping { max-width: 115px; } @media only screen and (max-width: 1200px) { - #server { - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } - } + #type { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } } @media only screen and (max-width: 720px) { - #server { - body { font-size: 10px; } - .content { padding: 0; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } - } + body { font-size: 10px; } + .content { padding: 0; } + #type { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } } @media only screen and (max-width: 620px) { - #server { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } - } + body { font-size: 10px; } + .content { padding: 0; } + #month_traffic { display:none; visibility:hidden; } + #type { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } } \ No newline at end of file diff --git a/web/css/light.css b/web/css/light.css index 37e7f775..811c8d09 100644 --- a/web/css/light.css +++ b/web/css/light.css @@ -17,35 +17,29 @@ tr.odd.expandRow > :hover { background: #FFF !important; } #month_traffic { min-width: 85px; max-width: 95px;} #network { min-width: 110px; } #cpu, #ram, #hdd { min-width: 45px; max-width: 90px; } -#ping { max-width: 110px; } +#ping { max-width: 115px; } @media only screen and (max-width: 1200px) { - #server { - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } - } + #type { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } } @media only screen and (max-width: 720px) { - #server { - body { font-size: 10px; } - .content { padding: 0; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } - } + body { font-size: 10px; } + .content { padding: 0; } + #type { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } } @media only screen and (max-width: 620px) { - #server { - body { font-size: 10px; } - .content { padding: 0; } - #month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; } - #type, tr td:nth-child(4) { display:none; visibility:hidden; } - #location, tr td:nth-child(5) { display:none; visibility:hidden; } - #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } - #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } - #ping, tr td:nth-child(13) { display:none; visibility:hidden; } - } + body { font-size: 10px; } + .content { padding: 0; } + #month_traffic { display:none; visibility:hidden; } + #type { display:none; visibility:hidden; } + #location, tr td:nth-child(5) { display:none; visibility:hidden; } + #uptime, tr td:nth-child(6) { display:none; visibility:hidden; } + #traffic, tr td:nth-child(9) { display:none; visibility:hidden; } + #ping, tr td:nth-child(13) { display:none; visibility:hidden; } } \ No newline at end of file From 6ab046be51683c064bf38a97e5236e184d9b9378 Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 22 Jan 2024 15:32:20 +0800 Subject: [PATCH 025/134] update --- clients/client-linux.py | 4 ++-- clients/client-psutil.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 9f3e3151..8de029df 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -18,7 +18,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 -ONLINE_PACKET_HISTORY_LEN = 1440 +ONLINE_PACKET_HISTORY_LEN = 10080 INTERVAL = 1 import socket @@ -520,7 +520,7 @@ def byte_str(object): array['tcp'], array['udp'], array['process'], array['thread'] = tupd() array['io_read'] = diskIO.get("read") array['io_write'] = diskIO.get("write") - array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100:.2f}%" for k, v in monitorServer.items()) + array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100:.1f}%" for k, v in monitorServer.items()) s.send(byte_str("update " + json.dumps(array) + "\n")) except KeyboardInterrupt: raise diff --git a/clients/client-psutil.py b/clients/client-psutil.py index 4e9c1f6f..4946a452 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -19,7 +19,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 -ONLINE_PACKET_HISTORY_LEN = 1440 +ONLINE_PACKET_HISTORY_LEN = 10080 INTERVAL = 1 import socket @@ -510,7 +510,7 @@ def byte_str(object): array['tcp'], array['udp'], array['process'], array['thread'] = tupd() array['io_read'] = diskIO.get("read") array['io_write'] = diskIO.get("write") - array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100:.2f}%" for k, v in monitorServer.items()) + array['custom'] = "
".join(f"{k}\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100:.2f}%" for k, v in monitorServer.items()) s.send(byte_str("update " + json.dumps(array) + "\n")) except KeyboardInterrupt: raise From 03446b8f29a1d5e6d4998281439aed12b170d587 Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 22 Jan 2024 15:34:44 +0800 Subject: [PATCH 026/134] update some for cl --- clients/client-linux.py | 2 -- clients/client-psutil.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 8de029df..8ebb3270 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -509,8 +509,6 @@ def byte_str(object): array['network_tx'] = netSpeed.get("nettx") array['network_in'] = NET_IN array['network_out'] = NET_OUT - # todo:兼容旧版本,下个版本删除ip_status - array['ip_status'] = True array['ping_10010'] = lostRate.get('10010') * 100 array['ping_189'] = lostRate.get('189') * 100 array['ping_10086'] = lostRate.get('10086') * 100 diff --git a/clients/client-psutil.py b/clients/client-psutil.py index 4946a452..278db936 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -499,8 +499,6 @@ def byte_str(object): array['network_tx'] = netSpeed.get("nettx") array['network_in'] = NET_IN array['network_out'] = NET_OUT - # todo:兼容旧版本,下个版本删除ip_status - array['ip_status'] = True array['ping_10010'] = lostRate.get('10010') * 100 array['ping_189'] = lostRate.get('189') * 100 array['ping_10086'] = lostRate.get('10086') * 100 From 8dfc6d4718fe209ea9160401d0e6e489e60c3eca Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 22 Jan 2024 19:49:29 +0800 Subject: [PATCH 027/134] update --- clients/client-linux.py | 1 + clients/client-psutil.py | 1 + 2 files changed, 2 insertions(+) diff --git a/clients/client-linux.py b/clients/client-linux.py index 8ebb3270..5a6bd1ca 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -455,6 +455,7 @@ def byte_str(object): if data.find("You are connecting via") < 0: data = byte_str(s.recv(1024)) print(data) + monitorServer.clear() for i in data.split('\n'): if "monitor" in i and "type" in i and "{" in i and "}" in i: jdata = json.loads(i[i.find("{"):i.find("}")+1]) diff --git a/clients/client-psutil.py b/clients/client-psutil.py index 278db936..da871b88 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -444,6 +444,7 @@ def byte_str(object): if data.find("You are connecting via") < 0: data = byte_str(s.recv(1024)) print(data) + monitorServer.clear() for i in data.split('\n'): if "monitor" in i and "type" in i and "{" in i and "}" in i: jdata = json.loads(i[i.find("{"):i.find("}")+1]) From eddf37c413667dc46b32d6845b33522ba6ae361f Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 23 Jan 2024 10:30:43 +0800 Subject: [PATCH 028/134] fix bug --- clients/client-linux.py | 17 ++++++++++------- clients/client-psutil.py | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 5a6bd1ca..fc65827a 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -324,13 +324,7 @@ def _monitor_thread(name, host, interval, type): packet_queue = Queue(maxsize=ONLINE_PACKET_HISTORY_LEN) while True: if name not in monitorServer.keys(): - monitorServer[name] = { - "type": type, - "dns_time": 0, - "connect_time": 0, - "download_time": 0, - "online_rate": 1 - } + break if packet_queue.full(): if packet_queue.get() == 0: lostPacket -= 1 @@ -459,6 +453,13 @@ def byte_str(object): for i in data.split('\n'): if "monitor" in i and "type" in i and "{" in i and "}" in i: jdata = json.loads(i[i.find("{"):i.find("}")+1]) + monitorServer[jdata.get("name")] = { + "type": jdata.get("type"), + "dns_time": 0, + "connect_time": 0, + "download_time": 0, + "online_rate": 1 + } t = threading.Thread( target=_monitor_thread, kwargs={ @@ -524,11 +525,13 @@ def byte_str(object): except KeyboardInterrupt: raise except socket.error: + monitorServer.clear() print("Disconnected...") if 's' in locals().keys(): del s time.sleep(3) except Exception as e: + monitorServer.clear() print("Caught Exception:", e) if 's' in locals().keys(): del s diff --git a/clients/client-psutil.py b/clients/client-psutil.py index da871b88..bcb8ea0a 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -312,13 +312,7 @@ def _monitor_thread(name, host, interval, type): packet_queue = Queue(maxsize=ONLINE_PACKET_HISTORY_LEN) while True: if name not in monitorServer.keys(): - monitorServer[name] = { - "type": type, - "dns_time": 0, - "connect_time": 0, - "download_time": 0, - "online_rate": 1 - } + break if packet_queue.full(): if packet_queue.get() == 0: lostPacket -= 1 @@ -444,10 +438,16 @@ def byte_str(object): if data.find("You are connecting via") < 0: data = byte_str(s.recv(1024)) print(data) - monitorServer.clear() for i in data.split('\n'): if "monitor" in i and "type" in i and "{" in i and "}" in i: jdata = json.loads(i[i.find("{"):i.find("}")+1]) + monitorServer[jdata.get("name")] = { + "type": jdata.get("type"), + "dns_time": 0, + "connect_time": 0, + "download_time": 0, + "online_rate": 1 + } t = threading.Thread( target=_monitor_thread, kwargs={ @@ -514,11 +514,13 @@ def byte_str(object): except KeyboardInterrupt: raise except socket.error: + monitorServer.clear() print("Disconnected...") if 's' in locals().keys(): del s time.sleep(3) except Exception as e: + monitorServer.clear() print("Caught Exception:", e) if 's' in locals().keys(): del s From 810f6a0d8a231ba676c46fc6e873d821a43102d9 Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 23 Jan 2024 16:47:26 +0800 Subject: [PATCH 029/134] fix --- web/js/serverstatus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/js/serverstatus.js b/web/js/serverstatus.js index 529456c0..02ca72b8 100644 --- a/web/js/serverstatus.js +++ b/web/js/serverstatus.js @@ -91,7 +91,7 @@ function uptime() { } if (!MableRow.length) { $("#monitors").append( - "" + + "" + "
加载中
" + "加载中" + "加载中" + From fb3ecd179651e81d12095e8eafc6bfe5dd9d002f Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 23 Jan 2024 17:43:27 +0800 Subject: [PATCH 030/134] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AAtod?= =?UTF-8?q?o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 +++++++++++++++------- server/config.json | 2 +- server/src/main.cpp | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a980f6c8..64b72c1e 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ cd ServerStatus/server && make #### 二、修改配置文件 ```diff -! watchdog rule 可以为任何已知字段的表达式 +! watchdog rule 可以为任何已知字段的表达式。注意Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,todo等待修复 ! watchdog interval 最小通知间隔 ! watchdog callback 可自定义为Post方法的URL,告警内容将拼接其后并发起回调 @@ -89,13 +89,21 @@ cd ServerStatus/server && make "location": "🇨🇳", "password": "USER_DEFAULT_PASSWORD", "monthstart": 1 - }, + } + ], + "monitors": [ + { + "name": "百度一下", + "host": "https://www.baidu.com", + "interval": 60, + "type": "https" + } ], "watchdog": [ { - "name": "服务器负载高监控,排除内存大于32G物理机,同时排除俄勒冈机器", - "rule": "cpu>90&load_1>4&memory_total<33554432&name!='俄勒冈'", + "name": "服务器负载高监控,排除内存大于32G物理机,同时排除node1机器", + "rule": "cpu>90&load_1>4&memory_total<33554432&name!='node1'", "interval": 600, "callback": "https://yourSMSurl" }, @@ -106,8 +114,8 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "服务器宕机告警,排出俄勒冈,排除s02", - "rule": "online4=0&online6=0&name!='俄勒冈'&username!='s02'", + "name": "服务器宕机告警,排出node1,排除s02", + "rule": "online4=0&online6=0&name!='node1'&username!='s02'", "interval": 600, "callback": "https://yourSMSurl" }, @@ -124,7 +132,7 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "你可以组合任何已知字段的表达式", + "name": "你可以组合任何已知字段的表达式,注意Exprtk库目前不支持中文等Unicode字符", "rule": "(hdd_used/hdd_total)*100>95", "interval": 1800, "callback": "https://yourSMSurl" diff --git a/server/config.json b/server/config.json index 29a4df47..aea25733 100644 --- a/server/config.json +++ b/server/config.json @@ -46,7 +46,7 @@ "type": "https" }, { - "name": "主机交流", + "name": "502论坛", "host": "https://www.hostloc.com", "interval": 60, "type": "https" diff --git a/server/src/main.cpp b/server/src/main.cpp index 2dc5c434..acada378 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -278,6 +278,23 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl int ID = 0; while (strcmp(Watchdog(ID)->m_aName, "NULL")) { +// Exprtk库默认使用窄字符类型,但可能会出现中文等Unicode字符无法正确解析的问题。 +// todo: 为解决此问题,可以使用宽字符类型替换Exprtk库中默认的窄字符类型。 +// #include +// #include +// #include +// typedef exprtk::expression expression_type; +// typedef exprtk::parser parser_type; +// int main() +// { +// std::wstring expression_string = L"sin(x)"; +// expression_type expression; +// parser_type parser; +// parser.compile(expression_string, expression); +// double x = 3.14; +// double result = expression.value(); +// return 0; +// } typedef exprtk::symbol_table symbol_table_t; typedef exprtk::expression expression_t; typedef exprtk::parser parser_t; From c236aee5dc38a92cf54e133a1b96b7f4b8ea6520 Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 23 Jan 2024 17:52:59 +0800 Subject: [PATCH 031/134] todo list --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 64b72c1e..c306d974 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ [![Python Support](https://img.shields.io/badge/python-3.6%2B%20-blue.svg)](https://github.com/cppla/ServerStatus) [![C++ Compiler](http://img.shields.io/badge/C++-GNU-blue.svg?style=flat&logo=cplusplus)](https://github.com/cppla/ServerStatus) [![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](https://github.com/cppla/ServerStatus) -[![Version](https://img.shields.io/badge/Version-Build%201.1.1-red)](https://github.com/cppla/ServerStatus) +[![Version](https://img.shields.io/badge/Version-Build%201.1.2-red)](https://github.com/cppla/ServerStatus) ![Latest Version](http://dl.cpp.la/Archive/serverstatus_1.0.9.png) -`Watchdog触发式告警,interval只是为了防止频繁收到报警信息造成的骚扰,并不是探测间隔。 同时为了防止海外机器闪断报警,也加入username、name、type等静态字符串参数的计算支持。` +`Watchdog触发式告警,interval只是为了防止频繁收到报警信息造成的骚扰,并不是探测间隔。 同时为了防止海外机器闪断报警,也加入username、name、type等静态字符串参数的计算支持。值得注意的是,Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,等待修复 ` # 目录: @@ -67,7 +67,7 @@ cd ServerStatus/server && make #### 二、修改配置文件 ```diff -! watchdog rule 可以为任何已知字段的表达式。注意Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,todo等待修复 +! watchdog rule 可以为任何已知字段的表达式。注意Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,等待修复 ! watchdog interval 最小通知间隔 ! watchdog callback 可自定义为Post方法的URL,告警内容将拼接其后并发起回调 @@ -132,7 +132,7 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "你可以组合任何已知字段的表达式,注意Exprtk库目前不支持中文等Unicode字符", + "name": "你可以组合任何已知字段的表达式", "rule": "(hdd_used/hdd_total)*100>95", "interval": 1800, "callback": "https://yourSMSurl" From 1f7827cc211e9b482bd3b8cfcd65c7cb719ff968 Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 23 Jan 2024 18:00:24 +0800 Subject: [PATCH 032/134] change --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c306d974..d5e0968a 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ cd ServerStatus/server && make ], "monitors": [ { - "name": "百度一下", + "name": "你可以监测自己的网站以及MySQL、Redis", "host": "https://www.baidu.com", "interval": 60, "type": "https" From 052c75ef23c79557d87c393b2ff483110a0707f7 Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 23 Jan 2024 18:09:23 +0800 Subject: [PATCH 033/134] update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5e0968a..f44c254a 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ cd ServerStatus/server && make ], "monitors": [ { - "name": "你可以监测自己的网站以及MySQL、Redis", + "name": "监测网站以及MySQL、Redis,默认为七天在线率", "host": "https://www.baidu.com", "interval": 60, "type": "https" From aa0ccd254c156931ca607059504958b861dd5aec Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 23 Jan 2024 18:50:15 +0800 Subject: [PATCH 034/134] update readme --- README.md | 5 +++-- server/config.json | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f44c254a..9026efd7 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,10 @@ [![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](https://github.com/cppla/ServerStatus) [![Version](https://img.shields.io/badge/Version-Build%201.1.2-red)](https://github.com/cppla/ServerStatus) -![Latest Version](http://dl.cpp.la/Archive/serverstatus_1.0.9.png) +![Latest Host Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_host.png) +![Latest Server Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_server.png) -`Watchdog触发式告警,interval只是为了防止频繁收到报警信息造成的骚扰,并不是探测间隔。 同时为了防止海外机器闪断报警,也加入username、name、type等静态字符串参数的计算支持。值得注意的是,Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,等待修复 ` +`Watchdog触发式告警,interval只是为了防止频繁收到报警信息造成的骚扰,并不是探测间隔。 同时为了防止海外机器闪断报警,也加入username、name、type等静态字符串参数的计算支持。值得注意的是,Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,等待修复。 ` # 目录: diff --git a/server/config.json b/server/config.json index aea25733..f3f0e40a 100644 --- a/server/config.json +++ b/server/config.json @@ -40,19 +40,19 @@ ], "monitors": [ { - "name": "百度一下", + "name": "baidu", "host": "https://www.baidu.com", "interval": 60, "type": "https" }, { - "name": "502论坛", + "name": "502BBS", "host": "https://www.hostloc.com", "interval": 60, "type": "https" }, { - "name": "DNS服务", + "name": "myDNS", "host": "114.114.114.114:53", "interval": 60, "type": "tcp" From 75d06c86660f124dd41cbee3690b1b29db0cf7cd Mon Sep 17 00:00:00 2001 From: cppla Date: Sat, 27 Jan 2024 15:27:10 +0800 Subject: [PATCH 035/134] add some ua --- clients/client-linux.py | 4 ++-- clients/client-psutil.py | 4 ++-- server/config.json | 8 +------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index fc65827a..5b1520d3 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -341,7 +341,7 @@ def _monitor_thread(name, host, interval, type): k = socket.create_connection((IP, 80), timeout=6) monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) m = timeit.default_timer() - k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nUser-Agent:ServerStatus/cppla\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) response = b"" while True: data = k.recv(4096) @@ -367,7 +367,7 @@ def _monitor_thread(name, host, interval, type): monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) m = timeit.default_timer() kk = context.wrap_socket(k, server_hostname=address) - kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nUser-Agent:ServerStatus/cppla\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) response = b"" while True: data = kk.recv(4096) diff --git a/clients/client-psutil.py b/clients/client-psutil.py index bcb8ea0a..3b566d8b 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -329,7 +329,7 @@ def _monitor_thread(name, host, interval, type): k = socket.create_connection((IP, 80), timeout=6) monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) m = timeit.default_timer() - k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nUser-Agent:ServerStatus/cppla\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) response = b"" while True: data = k.recv(4096) @@ -355,7 +355,7 @@ def _monitor_thread(name, host, interval, type): monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000) m = timeit.default_timer() kk = context.wrap_socket(k, server_hostname=address) - kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) + kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nUser-Agent:ServerStatus/cppla\r\nConnection:close\r\n\r\n".format(address).encode('utf-8')) response = b"" while True: data = kk.recv(4096) diff --git a/server/config.json b/server/config.json index f3f0e40a..9122e5e3 100644 --- a/server/config.json +++ b/server/config.json @@ -46,13 +46,7 @@ "type": "https" }, { - "name": "502BBS", - "host": "https://www.hostloc.com", - "interval": 60, - "type": "https" - }, - { - "name": "myDNS", + "name": "114", "host": "114.114.114.114:53", "interval": 60, "type": "tcp" From dc3868998a9a3cdcfb6a821ee22cbe3274e65532 Mon Sep 17 00:00:00 2001 From: cppla Date: Sun, 4 Feb 2024 14:37:39 +0800 Subject: [PATCH 036/134] 256->512 --- server/src/network.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/network.h b/server/src/network.h index 920d36f4..49187f85 100644 --- a/server/src/network.h +++ b/server/src/network.h @@ -10,7 +10,7 @@ enum NET_CONNSTATE_ERROR=4, NET_MAX_PACKETSIZE = 1400, - NET_MAX_CLIENTS = 256 + NET_MAX_CLIENTS = 512 }; typedef int (*NETFUNC_DELCLIENT)(int ClientID, const char* pReason, void *pUser); From a8b9b2d00d6dab6975e9842e750d7b9ea1a82aca Mon Sep 17 00:00:00 2001 From: cppla Date: Sun, 4 Feb 2024 14:43:19 +0800 Subject: [PATCH 037/134] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E4=B8=80=E5=A4=A9?= =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/client-linux.py | 4 ++-- clients/client-psutil.py | 4 ++-- server/config.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 5b1520d3..c014229b 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -3,7 +3,7 @@ # Update by : https://github.com/cppla/ServerStatus, Update date: 20220530 # 版本:1.0.3, 支持Python版本:2.7 to 3.10 # 支持操作系统: Linux, OSX, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures -# ONLINE_PACKET_HISTORY_LEN, 探测间隔60s,记录24小时在线率(1440);探测间隔60s,记录7天(10080);探测时间30s,记录24小时(2880) +# ONLINE_PACKET_HISTORY_LEN, 探测间隔120s,记录24小时在线率(720);探测时间180s,记录24小时(480);探测间隔60s,记录7天(10080) # 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义,例如:CU = "www.facebook.com"。 SERVER = "127.0.0.1" @@ -18,7 +18,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 -ONLINE_PACKET_HISTORY_LEN = 10080 +ONLINE_PACKET_HISTORY_LEN = 480 INTERVAL = 1 import socket diff --git a/clients/client-psutil.py b/clients/client-psutil.py index 3b566d8b..19743e75 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -4,7 +4,7 @@ # 依赖于psutil跨平台库 # 版本:1.0.3, 支持Python版本:2.7 to 3.10 # 支持操作系统: Linux, Windows, OSX, Sun Solaris, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures -# ONLINE_PACKET_HISTORY_LEN, 探测间隔60s,记录24小时在线率(1440);探测时间60s,记录7天在线率(10080);探测时间30s,记录24小时(2880) +# ONLINE_PACKET_HISTORY_LEN, 探测间隔120s,记录24小时在线率(720);探测时间180s,记录24小时(480);探测间隔60s,记录7天(10080) # 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义,例如:CU = "www.facebook.com"。 SERVER = "127.0.0.1" @@ -19,7 +19,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 -ONLINE_PACKET_HISTORY_LEN = 10080 +ONLINE_PACKET_HISTORY_LEN = 480 INTERVAL = 1 import socket diff --git a/server/config.json b/server/config.json index 9122e5e3..f9c13766 100644 --- a/server/config.json +++ b/server/config.json @@ -42,13 +42,13 @@ { "name": "baidu", "host": "https://www.baidu.com", - "interval": 60, + "interval": 180, "type": "https" }, { "name": "114", "host": "114.114.114.114:53", - "interval": 60, + "interval": 180, "type": "tcp" } ], From 25f878a38a3a8a15bcd9d3ef91deeda8cb208588 Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 11 Mar 2024 15:03:57 +0800 Subject: [PATCH 038/134] =?UTF-8?q?5=E5=88=86=E9=92=9F=E4=B8=80=E6=AC=A1pr?= =?UTF-8?q?obe=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/client-linux.py | 2 +- clients/client-psutil.py | 2 +- server/config.json | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index c014229b..7d9e4b5d 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -3,7 +3,7 @@ # Update by : https://github.com/cppla/ServerStatus, Update date: 20220530 # 版本:1.0.3, 支持Python版本:2.7 to 3.10 # 支持操作系统: Linux, OSX, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures -# ONLINE_PACKET_HISTORY_LEN, 探测间隔120s,记录24小时在线率(720);探测时间180s,记录24小时(480);探测间隔60s,记录7天(10080) +# ONLINE_PACKET_HISTORY_LEN, 探测间隔120s,记录24小时在线率(720);探测时间300s,记录24小时(288);探测间隔60s,记录7天(10080) # 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义,例如:CU = "www.facebook.com"。 SERVER = "127.0.0.1" diff --git a/clients/client-psutil.py b/clients/client-psutil.py index 19743e75..42a9d9bb 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -4,7 +4,7 @@ # 依赖于psutil跨平台库 # 版本:1.0.3, 支持Python版本:2.7 to 3.10 # 支持操作系统: Linux, Windows, OSX, Sun Solaris, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures -# ONLINE_PACKET_HISTORY_LEN, 探测间隔120s,记录24小时在线率(720);探测时间180s,记录24小时(480);探测间隔60s,记录7天(10080) +# ONLINE_PACKET_HISTORY_LEN, 探测间隔120s,记录24小时在线率(720);探测时间300s,记录24小时(288);探测间隔60s,记录7天(10080) # 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义,例如:CU = "www.facebook.com"。 SERVER = "127.0.0.1" diff --git a/server/config.json b/server/config.json index f9c13766..de79f188 100644 --- a/server/config.json +++ b/server/config.json @@ -42,13 +42,19 @@ { "name": "baidu", "host": "https://www.baidu.com", - "interval": 180, + "interval": 300, + "type": "https" + }, + { + "name": "aliyun", + "host": "https://www.aliyun.com", + "interval": 300, "type": "https" }, { "name": "114", "host": "114.114.114.114:53", - "interval": 180, + "interval": 300, "type": "tcp" } ], From 6331d7d45b9bf861e06ab7aaa3118a7573697f23 Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 11 Mar 2024 15:06:47 +0800 Subject: [PATCH 039/134] update --- clients/client-linux.py | 2 +- clients/client-psutil.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/client-linux.py b/clients/client-linux.py index 7d9e4b5d..a9d5dc2a 100755 --- a/clients/client-linux.py +++ b/clients/client-linux.py @@ -18,7 +18,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 -ONLINE_PACKET_HISTORY_LEN = 480 +ONLINE_PACKET_HISTORY_LEN = 288 INTERVAL = 1 import socket diff --git a/clients/client-psutil.py b/clients/client-psutil.py index 42a9d9bb..d3038095 100755 --- a/clients/client-psutil.py +++ b/clients/client-psutil.py @@ -19,7 +19,7 @@ PROBEPORT = 80 PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6 PING_PACKET_HISTORY_LEN = 100 -ONLINE_PACKET_HISTORY_LEN = 480 +ONLINE_PACKET_HISTORY_LEN = 288 INTERVAL = 1 import socket From f91279406876846c6c5fe5cd6e5c17aad44ecc46 Mon Sep 17 00:00:00 2001 From: cppla Date: Tue, 2 Apr 2024 10:24:12 +0800 Subject: [PATCH 040/134] add todo --- server/src/main.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index acada378..9eb6a4a9 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -110,13 +110,6 @@ void CMain::OnDelClient(int ClientNetID) { int ClientID = ClientNetToClient(ClientNetID); dbg_msg("main", "OnDelClient(ncid=%d, cid=%d)", ClientNetID, ClientID); - //copy offline message for watchdog - WatchdogMessage(ClientNetID, - 0, 0, 0, 0, 0, 0, - 0, 0, 0,0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0,0, 0, 0, - 0, 0, 0, 0); if(ClientID >= 0 && ClientID < NET_MAX_CLIENTS) { Client(ClientID)->m_Connected = false; @@ -124,6 +117,13 @@ void CMain::OnDelClient(int ClientNetID) Client(ClientID)->m_ClientNetType = NETTYPE_INVALID; mem_zero(&Client(ClientID)->m_Stats, sizeof(CClient::CStats)); } + //copy offline message for watchdog + WatchdogMessage(ClientNetID, + 0, 0, 0, 0, 0, 0, + 0, 0, 0,0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0,0, 0, 0, + 0, 0, 0, 0); } int CMain::HandleMessage(int ClientNetID, char *pMessage) @@ -353,6 +353,11 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl time_t currentStamp = (long long)time(/*ago*/0); if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval) { + if (!Client(ClientID)->m_Stats.m_Online4 && !Client(ClientID)->m_Stats.m_Online6) + { + //休眠5分钟如果5分钟后状态发生了变更,消息不发出。 + printf("download\n"); + } Client(ClientID)->m_AlarmLastTime = currentStamp; CURL *curl; CURLcode res; From 388938e02bf33ce9a5cf329b93a2015cb4ccd9d8 Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 16:39:08 +0800 Subject: [PATCH 041/134] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BA=86=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E9=97=AA=E6=96=AD=E5=AF=BC=E8=87=B4=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=8A=A5=E8=AD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/main.cpp | 110 +++++++++++++++++++++++++++++++++++++++++--- server/src/main.h | 4 +- 2 files changed, 106 insertions(+), 8 deletions(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index 9eb6a4a9..743fe916 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -117,13 +117,9 @@ void CMain::OnDelClient(int ClientNetID) Client(ClientID)->m_ClientNetType = NETTYPE_INVALID; mem_zero(&Client(ClientID)->m_Stats, sizeof(CClient::CStats)); } - //copy offline message for watchdog - WatchdogMessage(ClientNetID, - 0, 0, 0, 0, 0, 0, - 0, 0, 0,0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0,0, 0, 0, - 0, 0, 0, 0); + m_OfflineAlarmThreadData.pClients = m_aClients; + m_OfflineAlarmThreadData.pWatchDogs = m_aCWatchDogs; + thread_create(offlineAlarmThread, &m_OfflineAlarmThreadData); } int CMain::HandleMessage(int ClientNetID, char *pMessage) @@ -503,6 +499,105 @@ void CMain::JSONUpdateThread(void *pUser) fs_rename(pConfig->m_aJSONFile, aJSONFileTmp); } +void CMain::offlineAlarmThread(void *pUser) +{ + CJSONUpdateThreadData *m_OfflineAlarmThreadData = (CJSONUpdateThreadData *)pUser; + CClient *pClients = m_OfflineAlarmThreadData->pClients; + CWatchDog *pWatchDogs = m_OfflineAlarmThreadData->pWatchDogs; + thread_sleep(6000); + if(!pClients->m_Connected) + { + int ID = 0; + while (strcmp(pWatchDogs[ID].m_aName, "NULL")) + { + typedef exprtk::symbol_table symbol_table_t; + typedef exprtk::expression expression_t; + typedef exprtk::parser parser_t; + const std::string expression_string = pWatchDogs[ID].m_aRule; + std::string username = pClients->m_aUsername; + std::string name = pClients->m_aName; + std::string type = pClients->m_aType; + std::string host = pClients->m_aHost; + std::string location = pClients->m_aLocation; + std::double_t online4 = pClients->m_Stats.m_Online4; + std::double_t online6 = pClients->m_Stats.m_Online6; + + symbol_table_t symbol_table; + symbol_table.add_stringvar("username", username); + symbol_table.add_stringvar("name", name); + symbol_table.add_stringvar("type", type); + symbol_table.add_stringvar("host", host); + symbol_table.add_stringvar("location", location); + symbol_table.add_variable("online4",online4); + symbol_table.add_variable("online6",online6); + symbol_table.add_constants(); + + expression_t expression; + expression.register_symbol_table(symbol_table); + + parser_t parser; + parser.compile(expression_string,expression); + + if (expression.value() > 0) + { + time_t currentStamp = (long long)time(/*ago*/0); + if ((currentStamp-pClients->m_AlarmLastTime) > pWatchDogs[ID].m_aInterval) + { + printf("客户端下线, Client disconnects and sends alert information\n"); + pClients->m_AlarmLastTime = currentStamp; + CURL *curl; + CURLcode res; + curl_global_init(CURL_GLOBAL_ALL); + + curl = curl_easy_init(); + if(curl) { + //standard time + char standardTime[32]= { 0 }; + strftime(standardTime, sizeof(standardTime), "%Y-%m-%d %H:%M:%S",localtime(¤tStamp)); + + //url encode, Rules conflict with url special characters,eg:&, del rules, by https://cpp.la, 2023-10-09 + char encodeBuffer[2048] = { 0 }; + sprintf(encodeBuffer, "【告警名称】 %s \n\n【告警时间】 %s \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s", + pWatchDogs[ID].m_aName, + standardTime, + pClients->m_aUsername, + pClients->m_aName, + pClients->m_aType, + pClients->m_aHost, + pClients->m_aLocation); + char *encodeUrl = curl_easy_escape(curl, encodeBuffer, strlen(encodeBuffer)); + + //standard url + char urlBuffer[2048] = { 0 }; + sprintf(urlBuffer, "%s%s",pWatchDogs[ID].m_aCallback, encodeUrl); + + + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_URL, urlBuffer); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS,"signature=ServerStatus"); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6L); + res = curl_easy_perform(curl); + if(res != CURLE_OK) + fprintf(stderr, "watchdog failed: %s\n", curl_easy_strerror(res)); + if(encodeUrl) + curl_free(encodeUrl); + curl_easy_cleanup(curl); + } + curl_global_cleanup(); + } + } + ID++; + } + } + else + { + printf("网络波动,No alarm information is sent due to network fluctuations\n"); + } +} + int CMain::ReadConfig() { // read and parse config @@ -701,6 +796,7 @@ int CMain::Run() m_JSONUpdateThreadData.m_ReloadRequired = 2; m_JSONUpdateThreadData.pClients = m_aClients; m_JSONUpdateThreadData.pConfig = &m_Config; + m_JSONUpdateThreadData.pWatchDogs = m_aCWatchDogs; void *LoadThread = thread_create(JSONUpdateThread, &m_JSONUpdateThreadData); //thread_detach(LoadThread); diff --git a/server/src/main.h b/server/src/main.h index 848d2468..36496613 100644 --- a/server/src/main.h +++ b/server/src/main.h @@ -101,10 +101,12 @@ class CMain { CClient *pClients; CConfig *pConfig; + CWatchDog *pWatchDogs; volatile short m_ReloadRequired; - } m_JSONUpdateThreadData; + } m_JSONUpdateThreadData, m_OfflineAlarmThreadData; static void JSONUpdateThread(void *pUser); + static void offlineAlarmThread(void *pUser); public: CMain(CConfig Config); From fdc5abacfcf7cff44ecdfdebf05ffb559f7444fd Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 16:42:40 +0800 Subject: [PATCH 042/134] fix bug for offline --- README.md | 6 +++--- server/config.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9026efd7..fe7b0059 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Python Support](https://img.shields.io/badge/python-3.6%2B%20-blue.svg)](https://github.com/cppla/ServerStatus) [![C++ Compiler](http://img.shields.io/badge/C++-GNU-blue.svg?style=flat&logo=cplusplus)](https://github.com/cppla/ServerStatus) [![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](https://github.com/cppla/ServerStatus) -[![Version](https://img.shields.io/badge/Version-Build%201.1.2-red)](https://github.com/cppla/ServerStatus) +[![Version](https://img.shields.io/badge/Version-Build%201.1.3-red)](https://github.com/cppla/ServerStatus) ![Latest Host Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_host.png) ![Latest Server Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_server.png) @@ -115,8 +115,8 @@ cd ServerStatus/server && make "callback": "https://yourSMSurl" }, { - "name": "服务器宕机告警,排出node1,排除s02", - "rule": "online4=0&online6=0&name!='node1'&username!='s02'", + "name": "服务器宕机告警", + "rule": "online4=0&online6=0", "interval": 600, "callback": "https://yourSMSurl" }, diff --git a/server/config.json b/server/config.json index de79f188..0a960568 100644 --- a/server/config.json +++ b/server/config.json @@ -72,8 +72,8 @@ "callback": "https://yourSMSurl" }, { - "name": "offline warning,exclude name node1", - "rule": "online4=0&online6=0&name!='node1'", + "name": "offline warning", + "rule": "online4=0&online6=0", "interval": 600, "callback": "https://yourSMSurl" }, From 91f11dad760d6b3e6201024f6c3dd7da644eda9a Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 17:16:32 +0800 Subject: [PATCH 043/134] =?UTF-8?q?=E5=B1=8F=E8=94=BD=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84nginx=E6=97=A5=E5=BF=97=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=81=A5=E5=BA=B7=E6=A3=80=E6=9F=A5wq?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2d9f0a01..1228fcb3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN pwd && ls -a # glibc env run FROM nginx:latest -RUN mkdir -p /ServerStatus/server/ +RUN mkdir -p /ServerStatus/server/ && ln -sf /dev/null /var/log/nginx/access.log && ln -sf /dev/null /var/log/nginx/error.log COPY --from=builder server /ServerStatus/server/ COPY --from=builder web /usr/share/nginx/html/ @@ -25,5 +25,5 @@ ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone EXPOSE 80 35601 - +HEALTHCHECK --interval=5s --timeout=3s --retries=3 CMD curl --fail http://localhost:80 || bash -c 'kill -s 15 -1 && (sleep 10; kill -s 9 -1)' CMD nohup sh -c '/etc/init.d/nginx start && /ServerStatus/server/sergate --config=/ServerStatus/server/config.json --web-dir=/usr/share/nginx/html' From d75d5438a3f58f3ea4a19b2a73238fcf3c00d37a Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 17:44:43 +0800 Subject: [PATCH 044/134] docker compose healthcheck --- docker-compose.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 47011997..5b935d20 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,11 @@ services: context: . dockerfile: Dockerfile image: serverstatus_server + healthcheck: + test: curl --fail http://localhost:80 || bash -c 'kill -s 15 -1 && (sleep 10; kill -s 9 -1)' + interval: 30s + timeout: 10s + retries: 5 container_name: serverstatus restart: unless-stopped networks: From 503037c7e2d4c1ae20929e8a65615f9ed8837640 Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 19:53:04 +0800 Subject: [PATCH 045/134] add two logs --- docker-compose.yml | 1 - server/src/main.cpp | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5b935d20..42f8e12b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,7 +24,6 @@ services: networks: serverstatus-network: - name: serverstatus-network ipam: config: - subnet: 172.23.0.0/24 diff --git a/server/src/main.cpp b/server/src/main.cpp index 743fe916..6b318da6 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -543,7 +543,7 @@ void CMain::offlineAlarmThread(void *pUser) time_t currentStamp = (long long)time(/*ago*/0); if ((currentStamp-pClients->m_AlarmLastTime) > pWatchDogs[ID].m_aInterval) { - printf("客户端下线, Client disconnects and sends alert information\n"); + printf("客户端下线且超过阈值, Client disconnects and sends alert information\n"); pClients->m_AlarmLastTime = currentStamp; CURL *curl; CURLcode res; @@ -588,6 +588,8 @@ void CMain::offlineAlarmThread(void *pUser) } curl_global_cleanup(); } + else + printf("客户端下线但未超过阈值,No alarm if the threshold is not exceeded\n"); } ID++; } @@ -596,6 +598,7 @@ void CMain::offlineAlarmThread(void *pUser) { printf("网络波动,No alarm information is sent due to network fluctuations\n"); } + fflush(stdout); } int CMain::ReadConfig() From 510567eaeca5403db3faef9839739140c8f27d14 Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 21:31:35 +0800 Subject: [PATCH 046/134] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A9=B4=E5=A4=B4?= =?UTF-8?q?=E4=B8=8D=E5=AF=B9=E9=A9=AC=E5=98=B4=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/main.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index 6b318da6..9109606b 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -119,6 +119,7 @@ void CMain::OnDelClient(int ClientNetID) } m_OfflineAlarmThreadData.pClients = m_aClients; m_OfflineAlarmThreadData.pWatchDogs = m_aCWatchDogs; + m_OfflineAlarmThreadData.m_ReloadRequired = ClientID; thread_create(offlineAlarmThread, &m_OfflineAlarmThreadData); } @@ -504,8 +505,9 @@ void CMain::offlineAlarmThread(void *pUser) CJSONUpdateThreadData *m_OfflineAlarmThreadData = (CJSONUpdateThreadData *)pUser; CClient *pClients = m_OfflineAlarmThreadData->pClients; CWatchDog *pWatchDogs = m_OfflineAlarmThreadData->pWatchDogs; + volatile short ClientID = m_OfflineAlarmThreadData->m_ReloadRequired; thread_sleep(6000); - if(!pClients->m_Connected) + if(!pClients[ClientID].m_Connected) { int ID = 0; while (strcmp(pWatchDogs[ID].m_aName, "NULL")) @@ -514,13 +516,13 @@ void CMain::offlineAlarmThread(void *pUser) typedef exprtk::expression expression_t; typedef exprtk::parser parser_t; const std::string expression_string = pWatchDogs[ID].m_aRule; - std::string username = pClients->m_aUsername; - std::string name = pClients->m_aName; - std::string type = pClients->m_aType; - std::string host = pClients->m_aHost; - std::string location = pClients->m_aLocation; - std::double_t online4 = pClients->m_Stats.m_Online4; - std::double_t online6 = pClients->m_Stats.m_Online6; + std::string username = pClients[ClientID].m_aUsername; + std::string name = pClients[ClientID].m_aName; + std::string type = pClients[ClientID].m_aType; + std::string host = pClients[ClientID].m_aHost; + std::string location = pClients[ClientID].m_aLocation; + std::double_t online4 = pClients[ClientID].m_Stats.m_Online4; + std::double_t online6 = pClients[ClientID].m_Stats.m_Online6; symbol_table_t symbol_table; symbol_table.add_stringvar("username", username); @@ -541,10 +543,10 @@ void CMain::offlineAlarmThread(void *pUser) if (expression.value() > 0) { time_t currentStamp = (long long)time(/*ago*/0); - if ((currentStamp-pClients->m_AlarmLastTime) > pWatchDogs[ID].m_aInterval) + if ((currentStamp-pClients[ClientID].m_AlarmLastTime) > pWatchDogs[ID].m_aInterval) { printf("客户端下线且超过阈值, Client disconnects and sends alert information\n"); - pClients->m_AlarmLastTime = currentStamp; + pClients[ClientID].m_AlarmLastTime = currentStamp; CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_ALL); @@ -560,11 +562,11 @@ void CMain::offlineAlarmThread(void *pUser) sprintf(encodeBuffer, "【告警名称】 %s \n\n【告警时间】 %s \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s", pWatchDogs[ID].m_aName, standardTime, - pClients->m_aUsername, - pClients->m_aName, - pClients->m_aType, - pClients->m_aHost, - pClients->m_aLocation); + pClients[ClientID].m_aUsername, + pClients[ClientID].m_aName, + pClients[ClientID].m_aType, + pClients[ClientID].m_aHost, + pClients[ClientID].m_aLocation); char *encodeUrl = curl_easy_escape(curl, encodeBuffer, strlen(encodeBuffer)); //standard url From 0fe01064a4d281ec663b504ba0d43d9c62b91ca0 Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 21:59:23 +0800 Subject: [PATCH 047/134] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe7b0059..53ef7ba8 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ![Latest Host Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_host.png) ![Latest Server Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_server.png) -`Watchdog触发式告警,interval只是为了防止频繁收到报警信息造成的骚扰,并不是探测间隔。 同时为了防止海外机器闪断报警,也加入username、name、type等静态字符串参数的计算支持。值得注意的是,Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,等待修复。 ` +`Watchdog触发式告警,interval只是为了防止频繁收到报警信息造成的骚扰,并不是探测间隔。值得注意的是,Exprtk库默认使用窄字符类型,中文等Unicode字符无法解析计算,等待修复。 ` # 目录: From 4e73e8185ec53626750bad70191feb1d6ba7cc89 Mon Sep 17 00:00:00 2001 From: cppla Date: Wed, 3 Apr 2024 22:06:15 +0800 Subject: [PATCH 048/134] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53ef7ba8..98c54763 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Python Support](https://img.shields.io/badge/python-3.6%2B%20-blue.svg)](https://github.com/cppla/ServerStatus) [![C++ Compiler](http://img.shields.io/badge/C++-GNU-blue.svg?style=flat&logo=cplusplus)](https://github.com/cppla/ServerStatus) [![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](https://github.com/cppla/ServerStatus) -[![Version](https://img.shields.io/badge/Version-Build%201.1.3-red)](https://github.com/cppla/ServerStatus) +[![Version](https://img.shields.io/badge/Version-Build%201.1.4-red)](https://github.com/cppla/ServerStatus) ![Latest Host Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_host.png) ![Latest Server Version](https://dl.cpp.la/Archive/serverstatus_1.1.2_server.png) From adb05818b99907dc6731b546e3512124d94228c7 Mon Sep 17 00:00:00 2001 From: cppla Date: Mon, 8 Apr 2024 14:25:53 +0800 Subject: [PATCH 049/134] =?UTF-8?q?=E6=94=B9=E4=B8=BA15=E7=A7=92=E5=86=8D?= =?UTF-8?q?=E6=AC=A1=E5=88=A4=E6=96=AD=E6=98=AF=E5=90=A6=E7=A6=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index 9109606b..bec8ae65 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -506,7 +506,7 @@ void CMain::offlineAlarmThread(void *pUser) CClient *pClients = m_OfflineAlarmThreadData->pClients; CWatchDog *pWatchDogs = m_OfflineAlarmThreadData->pWatchDogs; volatile short ClientID = m_OfflineAlarmThreadData->m_ReloadRequired; - thread_sleep(6000); + thread_sleep(15000); if(!pClients[ClientID].m_Connected) { int ID = 0; From 08f15ebdc5499347592da4a72d2e8342e114b677 Mon Sep 17 00:00:00 2001 From: cppla Date: Thu, 18 Apr 2024 15:34:43 +0800 Subject: [PATCH 050/134] 15s -> 25s --- server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main.cpp b/server/src/main.cpp index bec8ae65..cc239e40 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -506,7 +506,7 @@ void CMain::offlineAlarmThread(void *pUser) CClient *pClients = m_OfflineAlarmThreadData->pClients; CWatchDog *pWatchDogs = m_OfflineAlarmThreadData->pWatchDogs; volatile short ClientID = m_OfflineAlarmThreadData->m_ReloadRequired; - thread_sleep(15000); + thread_sleep(25000); if(!pClients[ClientID].m_Connected) { int ID = 0; From d9e8f8a7c12bc948198e4529255c7e565240c786 Mon Sep 17 00:00:00 2001 From: cppla Date: Thu, 15 Aug 2024 14:02:33 +0800 Subject: [PATCH 051/134] del ie --- web/index.html | 5 - web/js/html5shiv.js | 326 ------------------------------------------ web/js/respond.min.js | 5 - 3 files changed, 336 deletions(-) delete mode 100644 web/js/html5shiv.js delete mode 100644 web/js/respond.min.js diff --git a/web/index.html b/web/index.html index 5fa61757..4b46318f 100644 --- a/web/index.html +++ b/web/index.html @@ -26,11 +26,6 @@ padding-bottom: 30px; } - -