diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index 7a8013ae01..1a963f0d9e 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -16,6 +16,20 @@ macro(import_target tname tdep tinclude tpath) ) endmacro() +# ETCD +if (MSVC) + set (ETCD_BUILD_COMMAND build.bat) +else() + set (ETCD_BUILD_COMMAND ./build) +endif() +ExternalProject_Add(etcd_build + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/etcd + CONFIGURE_COMMAND "" + BUILD_IN_SOURCE TRUE + BUILD_COMMAND "${ETCD_BUILD_COMMAND}" + INSTALL_COMMAND "") + + # ZLIB if (UNIX) ExternalProject_Add(zlib_build diff --git a/CHANGELOG b/CHANGELOG index f67fc8da37..a9763f4aa2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,14 @@ v3.0.0 (XXXX-XX-XX) ------------------- +* The order of AQL functions VALUES and KEYS has never been guaranteed and +by accident it had the "correct" ordering when iteratoring over Objects that +were not loaded from the database. This behaviour is now changed by +introduction of VelocyPack and no ordering is guaranteed unless you specify +the do sort parameter. + +* removed configure option `--enable-logger` + * added AQL array comparison operators All AQL comparison operators now lso exist in an array variant. In the @@ -294,7 +302,9 @@ v2.8.0-beta7 (2016-01-06) FOR doc IN collection COLLECT AGGREGATE minAge = MIN(doc.age), maxAge = MAX(doc.age) - RETURN { minAge, maxAge } + RETURN { + minAge, maxAge +} Only specific expressions are allowed on the right-hand side of each `AGGREGATE` assignment: diff --git a/CMakeLists.txt b/CMakeLists.txt index d005d24309..65d922b930 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,13 +103,28 @@ endif() # TODO: Exclude non-supported? ## Compiler flags -------------------------------------------------------------- + +# Build types +string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TL) +message (${CMAKE_BUILD_TYPE_TL}) +if(CMAKE_BUILD_TYPE_TL MATCHES debug) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g") +elseif(CMAKE_BUILD_TYPE_TL MATCHES relwithdebinfo) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -g") +elseif(CMAKE_BUILD_TYPE_TL MATCHES release) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") +endif() + # GCC if (CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu89 -g -O2") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -g -O2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu89") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") endif () if (CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif () if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") @@ -122,7 +137,7 @@ endif() # OSX if (APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O2 -std=c++11") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") if (CMAKE_COMPILER_IS_CLANG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") add_definitions("-Wno-deprecated-declarations") @@ -756,3 +771,4 @@ endif () # Finally: user cpack include(CPack) + diff --git a/Documentation/Books/Users/Aql/DocumentFunctions.mdpp b/Documentation/Books/Users/Aql/DocumentFunctions.mdpp index d3b4c40337..6323c137f7 100644 --- a/Documentation/Books/Users/Aql/DocumentFunctions.mdpp +++ b/Documentation/Books/Users/Aql/DocumentFunctions.mdpp @@ -113,7 +113,7 @@ AQL supports the following functions to operate on document values: - *VALUES(document, removeInternal)*: Returns the attribute values of the *document* as an array. If *removeInternal* is set to *true*, then all internal attributes (such - as *_id*, *_key* etc.) are removed from the result. + as *_id*, *_key* etc.) are removed from the result. The values will be returned in any order. - *ZIP(attributes, values)*: Returns a document object assembled from the separate parameters *attributes* and *values*. *attributes* and *values* must be diff --git a/arangod/Aql/AqlValue.cpp b/arangod/Aql/AqlValue.cpp index 4a23ff3cdf..b90460362f 100644 --- a/arangod/Aql/AqlValue.cpp +++ b/arangod/Aql/AqlValue.cpp @@ -37,6 +37,11 @@ using namespace arangodb::aql; using Json = arangodb::basics::Json; using JsonHelper = arangodb::basics::JsonHelper; +AqlValue::AqlValue(AqlValue$ const& other) : _json(nullptr), _type(JSON) { + _json = new Json(TRI_UNKNOWN_MEM_ZONE, arangodb::basics::VelocyPackHelper::velocyPackToJson(other.slice())); + TRI_ASSERT(_json != nullptr); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief a quick method to decide whether a value is true //////////////////////////////////////////////////////////////////////////////// @@ -723,20 +728,165 @@ Json AqlValue::toJson(arangodb::AqlTransaction* trx, THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } -// NOTE IMPORTANT: During the moving Process of shaped => VPACK -// This function is slower than toJson(). -// It is just used for validation purposes of the callers -std::shared_ptr> AqlValue::toVelocyPack( - arangodb::AqlTransaction* trx, TRI_document_collection_t const* document, - bool copy) const { +//////////////////////////////////////////////////////////////////////////////// +/// @brief Constructor +//////////////////////////////////////////////////////////////////////////////// + +AqlValue$::AqlValue$(VPackBuilder const& data) { + TRI_ASSERT(data.isClosed()); + VPackValueLength l = data.size(); + if (l < 16) { + // Use internal + memcpy(_data.internal, data.data(), l); + _data.internal[15] = AqlValueType::INTERNAL; + } else { + // Use external + _data.external = new VPackBuffer(l); + memcpy(_data.external->data(), data.data(), l); + _data.internal[15] = AqlValueType::EXTERNAL; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Constructor +//////////////////////////////////////////////////////////////////////////////// + +AqlValue$::AqlValue$(VPackBuilder const* data) : AqlValue$(*data){}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Constructor +//////////////////////////////////////////////////////////////////////////////// + +AqlValue$::AqlValue$(VPackSlice const& data) { + VPackValueLength l = data.byteSize(); + if (l < 16) { + // Use internal + memcpy(_data.internal, data.start(), l); + _data.internal[15] = AqlValueType::INTERNAL; + } else { + // Use external + _data.external = new VPackBuffer(l); + memcpy(_data.external->data(), data.start(), l); + _data.internal[15] = AqlValueType::EXTERNAL; + } +}; + + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Copy Constructor. +//////////////////////////////////////////////////////////////////////////////// + +AqlValue$::AqlValue$(AqlValue$ const& other) { + VPackSlice s = other.slice(); + VPackValueLength length = s.byteSize(); + if (other.type()) { + // Isse external + _data.external = new VPackBuffer(length); + memcpy(_data.external->data(), other._data.external->data(), length); + _data.internal[15] = AqlValueType::EXTERNAL; + } else { + memcpy(_data.internal, other._data.internal, length); + _data.internal[15] = AqlValueType::INTERNAL; + } +} + +// Temporary constructor to transform an old AqlValue to a new VPackBased +// AqlValue +AqlValue$::AqlValue$(AqlValue const& other, arangodb::AqlTransaction* trx, + TRI_document_collection_t const* document) { VPackBuilder builder; - toVelocyPack(trx, document, copy, builder); - return builder.steal(); + switch (other._type) { + case AqlValue::JSON: { + TRI_ASSERT(other._json != nullptr); + // TODO: Internal is still JSON. We always copy. + int res = arangodb::basics::JsonHelper::toVelocyPack(other._json->json(), builder); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + break; + } + case AqlValue::SHAPED: { + TRI_ASSERT(document != nullptr); + TRI_ASSERT(other._marker != nullptr); + auto shaper = document->getShaper(); + Json tmp = TRI_ExpandShapedJson(shaper, trx->resolver(), + document->_info.id(), other._marker); + int res = arangodb::basics::JsonHelper::toVelocyPack(tmp.json(), builder); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + break; + } + case AqlValue::DOCVEC: { + TRI_ASSERT(other._vector != nullptr); + try { + VPackArrayBuilder b(&builder); + for (auto const& current : *other._vector) { + size_t const n = current->size(); + auto vecCollection = current->getDocumentCollection(0); + for (size_t i = 0; i < n; ++i) { + current->getValueReference(i, 0) + .toVelocyPack(trx, vecCollection, builder); + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + break; + } + case AqlValue::RANGE: { + // TODO Has to be replaced by VPackCustom Type + TRI_ASSERT(other._range != nullptr); + try { + VPackArrayBuilder b(&builder); + size_t const n = other._range->size(); + for (size_t i = 0; i < n; ++i) { + builder.add(VPackValue(other._range->at(i))); + } + } catch (...) { + } + break; + } + case AqlValue::EMPTY: { + builder.add(VPackValue(VPackValueType::Null)); + break; + } + default: { + TRI_ASSERT(false); + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + } + VPackValueLength length = builder.size(); + if (length < 16) { + // Small enough for local + // copy memory from the builder into the internal data. + memcpy(_data.internal, builder.data(), length); + _data.internal[15] = AqlValueType::INTERNAL; + } else { + // We need a large external buffer + // TODO: Replace by SlimBuffer + _data.external = new VPackBuffer(length); + memcpy(_data.external->data(), builder.data(), length); + _data.internal[15] = AqlValueType::EXTERNAL; + } +} + +AqlValue$::AqlValueType AqlValue$::type() const { + return static_cast(_data.internal[15]); +} + +VPackSlice AqlValue$::slice() const { + if (type()) { + // Use External + return VPackSlice(_data.external->data()); + } else { + return VPackSlice(_data.internal); + } } void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx, TRI_document_collection_t const* document, - bool copy, VPackBuilder& builder) const { + VPackBuilder& builder) const { switch (_type) { case JSON: { TRI_ASSERT(_json != nullptr); @@ -745,17 +895,19 @@ void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx, if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } + break; } case SHAPED: { TRI_ASSERT(document != nullptr); TRI_ASSERT(_marker != nullptr); auto shaper = document->getShaper(); Json tmp = TRI_ExpandShapedJson(shaper, trx->resolver(), - document->_info.id(), _marker); + document->_info.id(), _marker); int res = arangodb::basics::JsonHelper::toVelocyPack(tmp.json(), builder); if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } + break; } case DOCVEC: { TRI_ASSERT(_vector != nullptr); @@ -766,14 +918,16 @@ void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx, auto vecCollection = current->getDocumentCollection(0); for (size_t i = 0; i < n; ++i) { current->getValueReference(i, 0) - .toVelocyPack(trx, vecCollection, true, builder); + .toVelocyPack(trx, vecCollection, builder); } } } catch (...) { THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } + break; } case RANGE: { + // TODO Has to be replaced by VPackCustom Type TRI_ASSERT(_range != nullptr); try { VPackArrayBuilder b(&builder); @@ -784,9 +938,11 @@ void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx, } catch (...) { THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } + break; } case EMPTY: { builder.add(VPackValue(VPackValueType::Null)); + break; } default: { TRI_ASSERT(false); diff --git a/arangod/Aql/AqlValue.h b/arangod/Aql/AqlValue.h index 641c22be0e..e83665643d 100644 --- a/arangod/Aql/AqlValue.h +++ b/arangod/Aql/AqlValue.h @@ -46,6 +46,9 @@ namespace aql { class AqlItemBlock; +// Temporary Forward +struct AqlValue$; + //////////////////////////////////////////////////////////////////////////////// /// @brief a struct to hold a value, registers hole AqlValue* during the /// execution @@ -89,6 +92,8 @@ struct AqlValue { _range = new Range(low, high); } + explicit AqlValue(AqlValue$ const& other); + ////////////////////////////////////////////////////////////////////////////// /// @brief destructor, doing nothing automatically! ////////////////////////////////////////////////////////////////////////////// @@ -284,15 +289,8 @@ struct AqlValue { arangodb::basics::Json toJson(arangodb::AqlTransaction*, TRI_document_collection_t const*, bool) const; - ////////////////////////////////////////////////////////////////////////////// - /// @brief toVelocyPack method - ////////////////////////////////////////////////////////////////////////////// - - std::shared_ptr> toVelocyPack( - arangodb::AqlTransaction*, TRI_document_collection_t const*, bool) const; - void toVelocyPack(arangodb::AqlTransaction*, TRI_document_collection_t const*, - bool, arangodb::velocypack::Builder&) const; + arangodb::velocypack::Builder&) const; ////////////////////////////////////////////////////////////////////////////// /// @brief creates a hash value for the AqlValue @@ -364,6 +362,69 @@ struct AqlValue { AqlValueType _type; }; +struct AqlValue$ { + public: + ////////////////////////////////////////////////////////////////////////////// + /// @brief AqlValueType, indicates what sort of value we have + ////////////////////////////////////////////////////////////////////////////// + + enum AqlValueType { INTERNAL, EXTERNAL }; + + ////////////////////////////////////////////////////////////////////////////// + /// @brief Holds the actual data for this AqlValue it has the following + /// semantics: + /// + /// All values with a size less than 16 will be stored directly in this + /// AqlValue using the data.internal structure. + /// All values of a larger size will be store in data.external. + /// The last bit of this union will be used to identify if we have to use + /// internal or external. + /// Delete of the Buffer should free every structure that is not using the + /// VPack external value type. + ////////////////////////////////////////////////////////////////////////////// + + private: + union { + char internal[16]; + arangodb::velocypack::Buffer* external; + } _data; + + public: + AqlValue$(arangodb::velocypack::Builder const&); + AqlValue$(arangodb::velocypack::Builder const*); + AqlValue$(arangodb::velocypack::Slice const&); + + AqlValue$(AqlValue const&, arangodb::AqlTransaction*, + TRI_document_collection_t const*); + + ~AqlValue$() { + if (type() && _data.external != nullptr) { + delete _data.external; + } + } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief Copy Constructor. + //////////////////////////////////////////////////////////////////////////////// + + AqlValue$(AqlValue$ const& other); + + ////////////////////////////////////////////////////////////////////////////// + /// @brief Returns the type of this value. If true it uses an external pointer + /// if false it uses the internal data structure + ////////////////////////////////////////////////////////////////////////////// + + // Read last bit of the union + AqlValueType type() const; + + ////////////////////////////////////////////////////////////////////////////// + /// @brief Returns a slice to read this Value's data + ////////////////////////////////////////////////////////////////////////////// + arangodb::velocypack::Slice slice() const; +}; + +static_assert(sizeof(AqlValue$) < 17, "invalid AqlValue size."); + } // closes namespace arangodb::aql } // closes namespace arangodb diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index 43c623147a..437e9d3bcd 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -1285,11 +1285,88 @@ TRI_json_t* AstNode::toJson(TRI_memory_zone_t* zone, bool verbose) const { ////////////////////////////////////////////////////////////////////////////// std::shared_ptr AstNode::toVelocyPackValue() const { - std::unique_ptr tmp(toJsonValue(TRI_UNKNOWN_MEM_ZONE)); - if (tmp == nullptr) { + auto builder = std::make_shared(); + if (builder == nullptr) { return nullptr; } - return arangodb::basics::JsonHelper::toVelocyPack(tmp.get()); + toVelocyPackValue(*builder); + return builder; +} + +////////////////////////////////////////////////////////////////////////////// +/// @brief build a VelocyPack representation of the node value +/// Can throw Out of Memory Error +////////////////////////////////////////////////////////////////////////////// + +void AstNode::toVelocyPackValue(VPackBuilder& builder) const { + if (type == NODE_TYPE_VALUE) { + // dump value of "value" node + switch (value.type) { + case VALUE_TYPE_NULL: + builder.add(VPackValue(VPackValueType::Null)); + break; + case VALUE_TYPE_BOOL: + builder.add(VPackValue(value.value._bool)); + break; + case VALUE_TYPE_INT: + builder.add(VPackValue(static_cast(value.value._int))); + break; + case VALUE_TYPE_DOUBLE: + builder.add(VPackValue(value.value._double)); + break; + case VALUE_TYPE_STRING: + builder.add(VPackValue(std::string(value.value._string, value.length))); + break; + } + return; + } + if (type == NODE_TYPE_ARRAY) { + { + VPackArrayBuilder guard(&builder); + size_t const n = numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = getMemberUnchecked(i); + if (member != nullptr) { + member->toVelocyPackValue(builder); + } + } + } + return; + } + + if (type == NODE_TYPE_OBJECT) { + { + size_t const n = numMembers(); + VPackObjectBuilder guard(&builder); + + for (size_t i = 0; i < n; ++i) { + auto member = getMemberUnchecked(i); + if (member != nullptr) { + builder.add(VPackValue(member->getStringValue())); + member->getMember(0)->toVelocyPackValue(builder); + } + } + } + return; + } + + if (type == NODE_TYPE_ATTRIBUTE_ACCESS) { + // TODO Could this be done more efficiently in the builder in place? + auto tmp = getMember(0)->toVelocyPackValue(); + if (tmp != nullptr) { + VPackSlice slice = tmp->slice(); + if (slice.isObject()) { + slice = slice.get(getStringValue()); + if (!slice.isNone()) { + builder.add(slice); + return; + } + } + builder.add(VPackValue(VPackValueType::Null)); + } + } + + // Do not add anything. } ////////////////////////////////////////////////////////////////////////////// @@ -1297,8 +1374,93 @@ std::shared_ptr AstNode::toVelocyPackValue() const { ////////////////////////////////////////////////////////////////////////////// std::shared_ptr AstNode::toVelocyPack(bool verbose) const { - std::unique_ptr tmp(toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); - return arangodb::basics::JsonHelper::toVelocyPack(tmp.get()); + auto builder = std::make_shared(); + if (builder == nullptr) { + return nullptr; + } + toVelocyPack(*builder, verbose); + return builder; +} + +////////////////////////////////////////////////////////////////////////////// +/// @brief Create a VelocyPack representation of the node +////////////////////////////////////////////////////////////////////////////// + +void AstNode::toVelocyPack(VPackBuilder& builder, bool verbose) const { + try { + VPackObjectBuilder guard(&builder); + + // dump node type + builder.add("type", VPackValue(getTypeString())); + if (verbose) { + builder.add("typeID", VPackValue(static_cast(type))); + } + if (type == NODE_TYPE_COLLECTION || type == NODE_TYPE_PARAMETER || + type == NODE_TYPE_ATTRIBUTE_ACCESS || + type == NODE_TYPE_OBJECT_ELEMENT || type == NODE_TYPE_FCALL_USER) { + // dump "name" of node + builder.add("name", VPackValue(getStringValue())); + } + if (type == NODE_TYPE_FCALL) { + auto func = static_cast(getData()); + builder.add("name", VPackValue(func->externalName)); + // arguments are exported via node members + } + + if (type == NODE_TYPE_ARRAY && hasFlag(DETERMINED_SORTED)) { + // transport information about a node's sortedness + builder.add("sorted", VPackValue(hasFlag(VALUE_SORTED))); + } + + if (type == NODE_TYPE_VALUE) { + // dump value of "value" node + builder.add(VPackValue("value")); + toVelocyPackValue(builder); + + if (verbose) { + builder.add("vType", VPackValue(getValueTypeString())); + builder.add("vTypeID", VPackValue(static_cast(value.type))); + } + } + + if (type == NODE_TYPE_OPERATOR_BINARY_IN || + type == NODE_TYPE_OPERATOR_BINARY_NIN || + type == NODE_TYPE_OPERATOR_BINARY_ARRAY_IN || + type == NODE_TYPE_OPERATOR_BINARY_ARRAY_NIN) { + builder.add("sorted", VPackValue(getBoolValue())); + } + if (type == NODE_TYPE_QUANTIFIER) { + std::string const quantifier(Quantifier::Stringify(getIntValue(true))); + builder.add("quantifier", VPackValue(quantifier)); + } + + if (type == NODE_TYPE_VARIABLE || type == NODE_TYPE_REFERENCE) { + auto variable = static_cast(getData()); + + TRI_ASSERT(variable != nullptr); + builder.add("name", VPackValue(variable->name)); + builder.add("id", VPackValue(static_cast(variable->id))); + } + + if (type == NODE_TYPE_EXPANSION) { + builder.add("levels", VPackValue(static_cast(getIntValue(true)))); + } + + // dump sub-nodes + size_t const n = members.size(); + if (n > 0) { + builder.add(VPackValue("subNodes")); + VPackArrayBuilder guard(&builder); + for (size_t i = 0; i < n; ++i) { + AstNode* member = getMemberUnchecked(i); + if (member != nullptr) { + member->toVelocyPack(builder, verbose); + } + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/AstNode.h b/arangod/Aql/AstNode.h index 1ee4236039..475be26df1 100644 --- a/arangod/Aql/AstNode.h +++ b/arangod/Aql/AstNode.h @@ -361,12 +361,25 @@ struct AstNode { std::shared_ptr toVelocyPackValue() const; + ////////////////////////////////////////////////////////////////////////////// + /// @brief build a VelocyPack representation of the node value + /// Can throw Out of Memory Error + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackValue(arangodb::velocypack::Builder&) const; + ////////////////////////////////////////////////////////////////////////////// /// @brief return a VelocyPack representation of the node ////////////////////////////////////////////////////////////////////////////// std::shared_ptr toVelocyPack(bool) const; + ////////////////////////////////////////////////////////////////////////////// + /// @brief Create a VelocyPack representation of the node + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(arangodb::velocypack::Builder&, bool) const; + ////////////////////////////////////////////////////////////////////////////// /// @brief adds a JSON representation of the node to the JSON array specified /// in the first argument diff --git a/arangod/Aql/ClusterNodes.cpp b/arangod/Aql/ClusterNodes.cpp index bb3e2b68ea..e20fa1c198 100644 --- a/arangod/Aql/ClusterNodes.cpp +++ b/arangod/Aql/ClusterNodes.cpp @@ -45,29 +45,26 @@ RemoteNode::RemoteNode(ExecutionPlan* plan, arangodb::basics::Json const& base) base.json(), "isResponsibleForInitCursor")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for RemoteNode +/// @brief toVelocyPack, for RemoteNode //////////////////////////////////////////////////////////////////////////////// -void RemoteNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - if (json.isEmpty()) { - return; - } +void RemoteNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName()))( - "server", arangodb::basics::Json(_server))( - "ownName", arangodb::basics::Json(_ownName))( - "queryId", arangodb::basics::Json(_queryId))( - "isResponsibleForInitCursor", - arangodb::basics::Json(_isResponsibleForInitCursor)); + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); + nodes.add("server", VPackValue(_server)); + nodes.add("ownName", VPackValue(_ownName)); + nodes.add("queryId", VPackValue(_queryId)); + nodes.add("isResponsibleForInitCursor", + VPackValue(_isResponsibleForInitCursor)); - // And add it: - nodes(json); + // And close it: + nodes.close(); } + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// @@ -97,22 +94,17 @@ ScatterNode::ScatterNode(ExecutionPlan* plan, JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for ScatterNode +/// @brief toVelocyPack, for ScatterNode //////////////////////////////////////////////////////////////////////////////// -void ScatterNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - if (json.isEmpty()) { - return; - } +void ScatterNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose); // call base class method - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName())); + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// @@ -145,26 +137,26 @@ DistributeNode::DistributeNode(ExecutionPlan* plan, _allowKeyConversionToObject(JsonHelper::checkAndGetBooleanValue( base.json(), "allowKeyConversionToObject")) {} -void DistributeNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for DistributedNode +//////////////////////////////////////////////////////////////////////////////// - if (json.isEmpty()) { - return; - } +void DistributeNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName()))( - "varId", arangodb::basics::Json(static_cast(_varId)))( - "alternativeVarId", - arangodb::basics::Json(static_cast(_alternativeVarId)))( - "createKeys", arangodb::basics::Json(_createKeys))( - "allowKeyConversionToObject", - arangodb::basics::Json(_allowKeyConversionToObject)); + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); + nodes.add("varId", VPackValue(static_cast(_varId))); + nodes.add("alternativeVarId", + VPackValue(static_cast(_alternativeVarId))); + nodes.add("createKeys", VPackValue(_createKeys)); + nodes.add("allowKeyConversionToObject", + VPackValue(_allowKeyConversionToObject)); - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// @@ -189,32 +181,29 @@ GatherNode::GatherNode(ExecutionPlan* plan, arangodb::basics::Json const& base, JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for GatherNode +/// @brief toVelocyPack, for GatherNode //////////////////////////////////////////////////////////////////////////////// -void GatherNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - if (json.isEmpty()) { - return; +void GatherNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); + + nodes.add(VPackValue("elements")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& it : _elements) { + VPackObjectBuilder obj(&nodes); + nodes.add(VPackValue("inVariable")); + it.first->toVelocyPack(nodes); + nodes.add("ascending", VPackValue(it.second)); + } } - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName())); - - arangodb::basics::Json values(arangodb::basics::Json::Array, - _elements.size()); - for (auto it = _elements.begin(); it != _elements.end(); ++it) { - arangodb::basics::Json element(arangodb::basics::Json::Object); - element("inVariable", (*it).first->toJson())( - "ascending", arangodb::basics::Json((*it).second)); - values(element); - } - json("elements", values); - - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ClusterNodes.h b/arangod/Aql/ClusterNodes.h index b435943bbe..05468257f5 100644 --- a/arangod/Aql/ClusterNodes.h +++ b/arangod/Aql/ClusterNodes.h @@ -92,11 +92,11 @@ class RemoteNode : public ExecutionNode { NodeType getType() const override final { return REMOTE; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -240,11 +240,11 @@ class ScatterNode : public ExecutionNode { NodeType getType() const override final { return SCATTER; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -333,11 +333,11 @@ class DistributeNode : public ExecutionNode { NodeType getType() const override final { return DISTRIBUTE; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -438,11 +438,11 @@ class GatherNode : public ExecutionNode { NodeType getType() const override final { return GATHER; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively diff --git a/arangod/Aql/CollectNode.cpp b/arangod/Aql/CollectNode.cpp index 558559df06..569f262297 100644 --- a/arangod/Aql/CollectNode.cpp +++ b/arangod/Aql/CollectNode.cpp @@ -54,76 +54,72 @@ CollectNode::CollectNode( CollectNode::~CollectNode() {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for CollectNode +/// @brief toVelocyPack, for CollectNode //////////////////////////////////////////////////////////////////////////////// -void CollectNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } +void CollectNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method // group variables + nodes.add(VPackValue("groups")); { - arangodb::basics::Json values(arangodb::basics::Json::Array, - _groupVariables.size()); - + VPackArrayBuilder guard(&nodes); for (auto const& groupVariable : _groupVariables) { - arangodb::basics::Json variable(arangodb::basics::Json::Object); - variable("outVariable", groupVariable.first->toJson())( - "inVariable", groupVariable.second->toJson()); - values(variable); + VPackObjectBuilder obj(&nodes); + nodes.add(VPackValue("outVariable")); + groupVariable.first->toVelocyPack(nodes); + nodes.add(VPackValue("inVariable")); + groupVariable.second->toVelocyPack(nodes); } - json("groups", values); } // aggregate variables + nodes.add(VPackValue("aggregates")); { - arangodb::basics::Json values(arangodb::basics::Json::Array, - _aggregateVariables.size()); - + VPackArrayBuilder guard(&nodes); for (auto const& aggregateVariable : _aggregateVariables) { - arangodb::basics::Json variable(arangodb::basics::Json::Object); - variable("outVariable", aggregateVariable.first->toJson())( - "inVariable", aggregateVariable.second.first->toJson()); - variable("type", arangodb::basics::Json(aggregateVariable.second.second)); - values(variable); + VPackObjectBuilder obj(&nodes); + nodes.add(VPackValue("outVariable")); + aggregateVariable.first->toVelocyPack(nodes); + nodes.add(VPackValue("inVariable")); + aggregateVariable.second.first->toVelocyPack(nodes); + nodes.add("type", VPackValue(aggregateVariable.second.second)); } - json("aggregates", values); } // expression variable might be empty if (_expressionVariable != nullptr) { - json("expressionVariable", _expressionVariable->toJson()); + nodes.add(VPackValue("expressionVariable")); + _expressionVariable->toVelocyPack(nodes); } // output variable might be empty if (_outVariable != nullptr) { - json("outVariable", _outVariable->toJson()); + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); } if (!_keepVariables.empty()) { - arangodb::basics::Json values(arangodb::basics::Json::Array, - _keepVariables.size()); - for (auto it = _keepVariables.begin(); it != _keepVariables.end(); ++it) { - arangodb::basics::Json variable(arangodb::basics::Json::Object); - variable("variable", (*it)->toJson()); - values(variable); + nodes.add(VPackValue("keepVariables")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& it : _keepVariables) { + VPackObjectBuilder obj(&nodes); + nodes.add(VPackValue("variable")); + it->toVelocyPack(nodes); + } } - json("keepVariables", values); } - json("count", arangodb::basics::Json(_count)); - json("isDistinctCommand", arangodb::basics::Json(_isDistinctCommand)); - json("specialized", arangodb::basics::Json(_specialized)); + nodes.add("count", VPackValue(_count)); + nodes.add("isDistinctCommand", VPackValue(_isDistinctCommand)); + nodes.add("specialized", VPackValue(_specialized)); + nodes.add(VPackValue("collectOptions")); + _options.toVelocyPack(nodes); - _options.toJson(json, zone); - - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectNode.h b/arangod/Aql/CollectNode.h index c732aa1872..e829c178c9 100644 --- a/arangod/Aql/CollectNode.h +++ b/arangod/Aql/CollectNode.h @@ -145,11 +145,11 @@ class CollectNode : public ExecutionNode { CollectOptions& getOptions() { return _options; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively diff --git a/arangod/Aql/CollectOptions.cpp b/arangod/Aql/CollectOptions.cpp index f681e3b515..38345608c1 100644 --- a/arangod/Aql/CollectOptions.cpp +++ b/arangod/Aql/CollectOptions.cpp @@ -24,6 +24,8 @@ #include "Aql/CollectOptions.h" #include "Basics/Exceptions.h" +#include + using namespace arangodb::aql; using Json = arangodb::basics::Json; using JsonHelper = arangodb::basics::JsonHelper; @@ -61,6 +63,15 @@ void CollectOptions::toJson(arangodb::basics::Json& json, json("collectOptions", options); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief convert the options to VelocyPack +//////////////////////////////////////////////////////////////////////////////// + +void CollectOptions::toVelocyPack(VPackBuilder& builder) const { + VPackObjectBuilder guard(&builder); + builder.add("method", VPackValue(methodToString(method))); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief get the aggregation method from a string //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectOptions.h b/arangod/Aql/CollectOptions.h index d4dab3cb38..c0f9ba1d8c 100644 --- a/arangod/Aql/CollectOptions.h +++ b/arangod/Aql/CollectOptions.h @@ -69,6 +69,13 @@ struct CollectOptions { void toJson(arangodb::basics::Json&, TRI_memory_zone_t*) const; + ////////////////////////////////////////////////////////////////////////////// + /// @brief convert the options to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(arangodb::velocypack::Builder&) const; + + ////////////////////////////////////////////////////////////////////////////// /// @brief get the aggregation method from a string ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Condition.cpp b/arangod/Aql/Condition.cpp index d64adc5aea..79f9e39cab 100644 --- a/arangod/Aql/Condition.cpp +++ b/arangod/Aql/Condition.cpp @@ -284,6 +284,19 @@ Condition::~Condition() { // all nodes belong to the AST } +////////////////////////////////////////////////////////////////////////////// +/// @brief export the condition as VelocyPack +////////////////////////////////////////////////////////////////////////////// + +void Condition::toVelocyPack(arangodb::velocypack::Builder& builder, + bool verbose) const { + if (_root == nullptr) { + VPackObjectBuilder guard(&builder); + } else { + _root->toVelocyPack(builder, verbose); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief create a condition from JSON //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Condition.h b/arangod/Aql/Condition.h index 494c4fc610..bc3945bdc6 100644 --- a/arangod/Aql/Condition.h +++ b/arangod/Aql/Condition.h @@ -237,6 +237,12 @@ class Condition { return arangodb::basics::Json(zone, _root->toJson(zone, verbose)); } + ////////////////////////////////////////////////////////////////////////////// + /// @brief export the condition as VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(arangodb::velocypack::Builder&, bool) const; + ////////////////////////////////////////////////////////////////////////////// /// @brief create a condition from JSON ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index 781128b0f5..851f178f46 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -426,11 +426,9 @@ struct CoordinatorInstanciator : public WalkerWorker { /// @brief generatePlanForOneShard ////////////////////////////////////////////////////////////////////////////// - arangodb::basics::Json generatePlanForOneShard(size_t nr, - EngineInfo const& info, - QueryId& connectedId, - std::string const& shardId, - bool verbose) { + void generatePlanForOneShard(VPackBuilder& builder, size_t nr, + EngineInfo const& info, QueryId& connectedId, + std::string const& shardId, bool verbose) { // copy the relevant fragment of the plan for each shard // Note that in these parts of the query there are no SubqueryNodes, // since they are all on the coordinator! @@ -462,7 +460,7 @@ struct CoordinatorInstanciator : public WalkerWorker { } plan.root(previous); plan.setVarUsageComputed(); - return plan.root()->toJson(TRI_UNKNOWN_MEM_ZONE, verbose); + return plan.root()->toVelocyPack(builder, verbose); } ////////////////////////////////////////////////////////////////////////////// @@ -605,11 +603,13 @@ struct CoordinatorInstanciator : public WalkerWorker { for (auto const& shardId : *shardIds) { // inject the current shard id into the collection collection->setCurrentShard(shardId); - auto jsonPlan = - generatePlanForOneShard(nr++, info, connectedId, shardId, true); + VPackBuilder b; + generatePlanForOneShard(b, nr++, info, connectedId, shardId, true); + + std::unique_ptr tmp(arangodb::basics::VelocyPackHelper::velocyPackToJson(b.slice())); distributePlanToShard(coordTransactionID, info, collection, connectedId, - shardId, jsonPlan.steal()); + shardId, tmp.release()); } // fix collection diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index af3d74a374..70c0fab9b2 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -428,23 +428,22 @@ ExecutionNode::ExecutionNode(ExecutionPlan* plan, } //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, export an ExecutionNode to JSON +/// @brief toVelocyPack, export an ExecutionNode to VelocyPack //////////////////////////////////////////////////////////////////////////////// -arangodb::basics::Json ExecutionNode::toJson(TRI_memory_zone_t* zone, - bool verbose) const { +void ExecutionNode::toVelocyPack(VPackBuilder& builder, bool verbose) const { ENTER_BLOCK - arangodb::basics::Json nodes = - arangodb::basics::Json(arangodb::basics::Json::Array, 10); - toJsonHelper(nodes, zone, verbose); - - arangodb::basics::Json json = - arangodb::basics::Json(arangodb::basics::Json::Object, 1)("nodes", nodes); - - return json; + VPackObjectBuilder obj(&builder); + builder.add(VPackValue("nodes")); + { + VPackArrayBuilder guard(&builder); + toVelocyPackHelper(builder, verbose); + } LEAVE_BLOCK } + + //////////////////////////////////////////////////////////////////////////////// /// @brief execution Node clone utility to be called by derives //////////////////////////////////////////////////////////////////////////////// @@ -656,117 +655,119 @@ Variable* ExecutionNode::varFromJson(Ast* ast, } //////////////////////////////////////////////////////////////////////////////// -/// @brief toJsonHelper, for a generic node +/// @brief toVelocyPackHelper, for a generic node +/// Note: The input nodes has to be an Array Element that is still Open. +/// At the end of this function the current-nodes Object is OPEN and +/// has to be closed. The initial caller of toVelocyPackHelper +/// has to close the array. //////////////////////////////////////////////////////////////////////////////// -arangodb::basics::Json ExecutionNode::toJsonHelperGeneric( - arangodb::basics::Json& nodes, TRI_memory_zone_t* zone, - bool verbose) const { +void ExecutionNode::toVelocyPackHelperGeneric(VPackBuilder& nodes, + bool verbose) const { ENTER_BLOCK + TRI_ASSERT(nodes.isOpenArray()); size_t const n = _dependencies.size(); for (size_t i = 0; i < n; i++) { - _dependencies[i]->toJsonHelper(nodes, zone, verbose); + _dependencies[i]->toVelocyPackHelper(nodes, verbose); } - - arangodb::basics::Json json(arangodb::basics::Json::Object, 5); - json("type", arangodb::basics::Json(getTypeString())); - + nodes.openObject(); + nodes.add("type", VPackValue(getTypeString())); if (verbose) { - json("typeID", arangodb::basics::Json(static_cast(getType()))); + nodes.add("typeID", VPackValue(static_cast(getType()))); } - - arangodb::basics::Json deps(arangodb::basics::Json::Array, n); - for (size_t i = 0; i < n; i++) { - deps(arangodb::basics::Json(static_cast(_dependencies[i]->id()))); - } - json("dependencies", deps); - - if (verbose) { - arangodb::basics::Json parents(arangodb::basics::Json::Array, - _parents.size()); - for (size_t i = 0; i < _parents.size(); i++) { - parents(arangodb::basics::Json(static_cast(_parents[i]->id()))); + nodes.add(VPackValue("dependencies")); // Open Key + { + VPackArrayBuilder guard(&nodes); + for (auto const& it : _dependencies) { + nodes.add(VPackValue(static_cast(it->id()))); } - json("parents", parents); } - - json("id", arangodb::basics::Json(static_cast(id()))); + if (verbose) { + nodes.add(VPackValue("parents")); // Open Key + VPackArrayBuilder guard(&nodes); + for (auto const& it : _parents) { + nodes.add(VPackValue(static_cast(it->id()))); + } + } + nodes.add("id", VPackValue(static_cast(id()))); size_t nrItems = 0; - json("estimatedCost", arangodb::basics::Json(getCost(nrItems))); - json("estimatedNrItems", - arangodb::basics::Json(static_cast(nrItems))); + nodes.add("estimatedCost", VPackValue(getCost(nrItems))); + nodes.add("estimatedNrItems", VPackValue(nrItems)); if (verbose) { - json("depth", arangodb::basics::Json(static_cast(_depth))); + nodes.add("depth", VPackValue(static_cast(_depth))); if (_registerPlan) { - arangodb::basics::Json jsonVarInfoList(arangodb::basics::Json::Array, - _registerPlan->varInfo.size()); - for (auto const& oneVarInfo : _registerPlan->varInfo) { - arangodb::basics::Json jsonOneVarInfoArray( - arangodb::basics::Json::Object, 2); - jsonOneVarInfoArray( - "VariableId", - arangodb::basics::Json(static_cast(oneVarInfo.first)))( - "depth", arangodb::basics::Json( - static_cast(oneVarInfo.second.depth)))( - "RegisterId", arangodb::basics::Json(static_cast( - oneVarInfo.second.registerId))); - jsonVarInfoList(jsonOneVarInfoArray); + nodes.add(VPackValue("varInfoList")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneVarInfo : _registerPlan->varInfo) { + VPackObjectBuilder guardInner(&nodes); + nodes.add("VariableId", + VPackValue(static_cast(oneVarInfo.first))); + nodes.add("depth", + VPackValue(static_cast(oneVarInfo.second.depth))); + nodes.add( + "RegisterId", + VPackValue(static_cast(oneVarInfo.second.registerId))); + } } - json("varInfoList", jsonVarInfoList); - - arangodb::basics::Json jsonNRRegsList(arangodb::basics::Json::Array, - _registerPlan->nrRegs.size()); - for (auto const& oneRegisterID : _registerPlan->nrRegs) { - jsonNRRegsList( - arangodb::basics::Json(static_cast(oneRegisterID))); + nodes.add(VPackValue("nrRegs")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneRegisterID : _registerPlan->nrRegs) { + nodes.add(VPackValue(static_cast(oneRegisterID))); + } } - json("nrRegs", jsonNRRegsList); - - arangodb::basics::Json jsonNRRegsHereList( - arangodb::basics::Json::Array, _registerPlan->nrRegsHere.size()); - for (auto const& oneRegisterID : _registerPlan->nrRegsHere) { - jsonNRRegsHereList( - arangodb::basics::Json(static_cast(oneRegisterID))); + nodes.add(VPackValue("nrRegsHere")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneRegisterID : _registerPlan->nrRegsHere) { + nodes.add(VPackValue(static_cast(oneRegisterID))); + } } - json("nrRegsHere", jsonNRRegsHereList); - json("totalNrRegs", arangodb::basics::Json( - static_cast(_registerPlan->totalNrRegs))); + nodes.add("totalNrRegs", VPackValue(_registerPlan->totalNrRegs)); } else { - json("varInfoList", - arangodb::basics::Json(arangodb::basics::Json::Array)); - json("nrRegs", arangodb::basics::Json(arangodb::basics::Json::Array)); - json("nrRegsHere", arangodb::basics::Json(arangodb::basics::Json::Array)); - json("totalNrRegs", arangodb::basics::Json(0.0)); + nodes.add(VPackValue("varInfoList")); + { + VPackArrayBuilder guard(&nodes); + } + nodes.add(VPackValue("nrRegs")); + { + VPackArrayBuilder guard(&nodes); + } + nodes.add(VPackValue("nrRegsHere")); + { + VPackArrayBuilder guard(&nodes); + } + nodes.add("totalNrRegs", VPackValue(0)); } - arangodb::basics::Json jsonRegsToClearList(arangodb::basics::Json::Array, - _regsToClear.size()); - for (auto const& oneRegisterID : _regsToClear) { - jsonRegsToClearList( - arangodb::basics::Json(static_cast(oneRegisterID))); - } - json("regsToClear", jsonRegsToClearList); - - arangodb::basics::Json jsonVarsUsedLaterList(arangodb::basics::Json::Array, - _varsUsedLater.size()); - for (auto const& oneVarUsedLater : _varsUsedLater) { - jsonVarsUsedLaterList.add(oneVarUsedLater->toJson()); + nodes.add(VPackValue("regsToClear")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneRegisterID : _regsToClear) { + nodes.add(VPackValue(static_cast(oneRegisterID))); + } } - json("varsUsedLater", jsonVarsUsedLaterList); - - arangodb::basics::Json jsonvarsValidList(arangodb::basics::Json::Array, - _varsValid.size()); - for (auto const& oneVarUsedLater : _varsValid) { - jsonvarsValidList.add(oneVarUsedLater->toJson()); + nodes.add(VPackValue("varsUsedLater")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneVar : _varsUsedLater) { + oneVar->toVelocyPack(nodes); + } } - json("varsValid", jsonvarsValidList); + nodes.add(VPackValue("varsValid")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneVar : _varsValid) { + oneVar->toVelocyPack(nodes); + } + } } - - return json; + TRI_ASSERT(nodes.isOpenObject()); LEAVE_BLOCK } @@ -1216,21 +1217,22 @@ SingletonNode::SingletonNode(ExecutionPlan* plan, arangodb::basics::Json const& base) : ExecutionNode(plan, base) {} -void SingletonNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for SingletonNode +//////////////////////////////////////////////////////////////////////////////// + +void SingletonNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } - - // And add it: - nodes(json); + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + // This node has no own information. + nodes.close(); LEAVE_BLOCK } + + //////////////////////////////////////////////////////////////////////////////// /// @brief the cost of a singleton is 1, it produces one item only //////////////////////////////////////////////////////////////////////////////// @@ -1250,28 +1252,24 @@ EnumerateCollectionNode::EnumerateCollectionNode( _random(JsonHelper::checkAndGetBooleanValue(base.json(), "random")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for EnumerateCollectionNode +/// @brief toVelocyPack, for EnumerateCollectionNode //////////////////////////////////////////////////////////////////////////////// -void EnumerateCollectionNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, - bool verbose) const { +void EnumerateCollectionNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method // Now put info about vocbase and cid in there - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName()))( - "outVariable", _outVariable->toJson())("random", - arangodb::basics::Json(_random)); + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); + nodes.add("random", VPackValue(_random)); - // And add it: - nodes(json); + // And close it: + nodes.close(); LEAVE_BLOCK } @@ -1320,23 +1318,22 @@ EnumerateListNode::EnumerateListNode(ExecutionPlan* plan, _outVariable(varFromJson(plan->getAst(), base, "outVariable")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for EnumerateListNode +/// @brief toVelocyPack, for EnumerateListNode //////////////////////////////////////////////////////////////////////////////// -void EnumerateListNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, - bool verbose) const { +void EnumerateListNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - if (json.isEmpty()) { - return; - } - json("inVariable", _inVariable->toJson())("outVariable", - _outVariable->toJson()); + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); - // And add it: - nodes(json); + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); + + // And close it: + nodes.close(); LEAVE_BLOCK } @@ -1429,24 +1426,19 @@ LimitNode::LimitNode(ExecutionPlan* plan, arangodb::basics::Json const& base) JsonHelper::checkAndGetBooleanValue(base.json(), "fullCount")) {} //////////////////////////////////////////////////////////////////////////////// -// @brief toJson, for LimitNode +// @brief toVelocyPack, for LimitNode //////////////////////////////////////////////////////////////////////////////// -void LimitNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { +void LimitNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - if (json.isEmpty()) { - return; - } - // Now put info about offset and limit in - json("offset", arangodb::basics::Json(static_cast(_offset)))( - "limit", arangodb::basics::Json(static_cast(_limit)))( - "fullCount", arangodb::basics::Json(_fullCount)); - // And add it: - nodes(json); + ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose); // call base class method + nodes.add("offset", VPackValue(static_cast(_offset))); + nodes.add("limit", VPackValue(static_cast(_limit))); + nodes.add("fullCount", VPackValue(_fullCount)); + + // And close it: + nodes.close(); LEAVE_BLOCK } @@ -1475,32 +1467,31 @@ CalculationNode::CalculationNode(ExecutionPlan* plan, _canRemoveIfThrows(false) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for CalculationNode +/// @brief toVelocyPack, for CalculationNode //////////////////////////////////////////////////////////////////////////////// -void CalculationNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, - bool verbose) const { +void CalculationNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + nodes.add(VPackValue("expression")); + _expression->toVelocyPack(nodes, verbose); - if (json.isEmpty()) { - return; - } + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); - json("expression", _expression->toJson(TRI_UNKNOWN_MEM_ZONE, verbose))( - "outVariable", _outVariable->toJson())( - "canThrow", arangodb::basics::Json(_expression->canThrow())); + nodes.add("canThrow", VPackValue(_expression->canThrow())); if (_conditionVariable != nullptr) { - json("conditionVariable", _conditionVariable->toJson()); + nodes.add(VPackValue("conditionVariable")); + _conditionVariable->toVelocyPack(nodes); } - json("expressionType", arangodb::basics::Json(_expression->typeString())); + nodes.add("expressionType", VPackValue(_expression->typeString())); - // And add it: - nodes(json); + // And close it + nodes.close(); LEAVE_BLOCK } @@ -1546,22 +1537,21 @@ SubqueryNode::SubqueryNode(ExecutionPlan* plan, _outVariable(varFromJson(plan->getAst(), base, "outVariable")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for SubqueryNode +/// @brief toVelocyPack, for SubqueryNode //////////////////////////////////////////////////////////////////////////////// -void SubqueryNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { +void SubqueryNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - if (json.isEmpty()) { - return; - } - json("subquery", _subquery->toJson(TRI_UNKNOWN_MEM_ZONE, verbose))( - "outVariable", _outVariable->toJson()); + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + nodes.add(VPackValue("subquery")); + _subquery->toVelocyPack(nodes, verbose); + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); // And add it: - nodes(json); + nodes.close(); LEAVE_BLOCK } @@ -1741,22 +1731,19 @@ FilterNode::FilterNode(ExecutionPlan* plan, arangodb::basics::Json const& base) _inVariable(varFromJson(plan->getAst(), base, "inVariable")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for FilterNode +/// @brief toVelocyPack, for FilterNode //////////////////////////////////////////////////////////////////////////////// -void FilterNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { +void FilterNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - if (json.isEmpty()) { - return; - } + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method - json("inVariable", _inVariable->toJson()); + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); - // And add it: - nodes(json); + // And close it: + nodes.close(); LEAVE_BLOCK } @@ -1799,23 +1786,20 @@ ReturnNode::ReturnNode(ExecutionPlan* plan, arangodb::basics::Json const& base) _inVariable(varFromJson(plan->getAst(), base, "inVariable")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for ReturnNode +/// @brief toVelocyPack, for ReturnNode //////////////////////////////////////////////////////////////////////////////// -void ReturnNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { +void ReturnNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method - if (json.isEmpty()) { - return; - } - json("inVariable", _inVariable->toJson()); + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); - // And add it: - nodes(json); + // And close it: + nodes.close(); LEAVE_BLOCK } @@ -1850,21 +1834,16 @@ double ReturnNode::estimateCost(size_t& nrItems) const { } //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for NoResultsNode +/// @brief toVelocyPack, for NoResultsNode //////////////////////////////////////////////////////////////////////////////// -void NoResultsNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { +void NoResultsNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method + ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose); - if (json.isEmpty()) { - return; - } - - // And add it: - nodes(json); + //And close it + nodes.close(); LEAVE_BLOCK } diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index dd568e6b94..3a99936f4d 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -35,6 +35,10 @@ #include "VocBase/vocbase.h" namespace arangodb { +namespace velocypack { +class Builder; +} + namespace aql { class Ast; struct Collection; @@ -448,18 +452,18 @@ class ExecutionNode { bool walk(WalkerWorker* worker); - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON, returns an AUTOFREE Json object - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// + /// @brief toVelocyPack, export an ExecutionNode to VelocyPack + /////////////////////////////////////////////////////////////////////////////// - arangodb::basics::Json toJson(TRI_memory_zone_t*, bool) const; + void toVelocyPack(arangodb::velocypack::Builder&, bool) const; ////////////////////////////////////////////////////////////////////////////// - /// @brief toJson + /// @brief toVelocyPack ////////////////////////////////////////////////////////////////////////////// - virtual void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const = 0; + virtual void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const = 0; ////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere, returning a vector @@ -699,11 +703,10 @@ class ExecutionNode { char const* which); ////////////////////////////////////////////////////////////////////////////// - /// @brief toJsonHelper, for a generic node + /// @brief toVelocyPackHelper, for a generic node ////////////////////////////////////////////////////////////////////////////// - arangodb::basics::Json toJsonHelperGeneric(arangodb::basics::Json&, - TRI_memory_zone_t*, bool) const; + void toVelocyPackHelperGeneric(arangodb::velocypack::Builder&, bool) const; ////////////////////////////////////////////////////////////////////////////// /// @brief set regs to be deleted @@ -829,11 +832,11 @@ class SingletonNode : public ExecutionNode { NodeType getType() const override final { return SINGLETON; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -892,11 +895,11 @@ class EnumerateCollectionNode : public ExecutionNode { NodeType getType() const override final { return ENUMERATE_COLLECTION; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -1000,11 +1003,11 @@ class EnumerateListNode : public ExecutionNode { NodeType getType() const override final { return ENUMERATE_LIST; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -1101,11 +1104,11 @@ class LimitNode : public ExecutionNode { NodeType getType() const override final { return LIMIT; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -1206,11 +1209,11 @@ class CalculationNode : public ExecutionNode { NodeType getType() const override final { return CALCULATION; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -1365,11 +1368,11 @@ class SubqueryNode : public ExecutionNode { Variable const* outVariable() const { return _outVariable; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -1484,11 +1487,11 @@ class FilterNode : public ExecutionNode { NodeType getType() const override final { return FILTER; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -1613,11 +1616,11 @@ class ReturnNode : public ExecutionNode { NodeType getType() const override final { return RETURN; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -1684,11 +1687,12 @@ class NoResultsNode : public ExecutionNode { NodeType getType() const override final { return NORESULTS; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index fb7c6d4849..30af76e6bc 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -214,7 +214,11 @@ ExecutionPlan* ExecutionPlan::clone(Query const& query) { arangodb::basics::Json ExecutionPlan::toJson(Ast* ast, TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json result = _root->toJson(zone, verbose); + // TODO + VPackBuilder b; + _root->toVelocyPack(b, verbose); + TRI_json_t* tmp = arangodb::basics::VelocyPackHelper::velocyPackToJson(b.slice()); + arangodb::basics::Json result(zone, tmp); // set up rules auto appliedRules(Optimizer::translateRules(_appliedRules)); diff --git a/arangod/Aql/Expression.h b/arangod/Aql/Expression.h index 143dc65bc3..50a711a476 100644 --- a/arangod/Aql/Expression.h +++ b/arangod/Aql/Expression.h @@ -153,6 +153,14 @@ class Expression { return arangodb::basics::Json(zone, _node->toJson(zone, verbose)); } + ////////////////////////////////////////////////////////////////////////////// + /// @brief return a VelocyPack representation of the expression + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(arangodb::velocypack::Builder& builder, bool verbose) const { + _node->toVelocyPack(builder, verbose); + } + ////////////////////////////////////////////////////////////////////////////// /// @brief execute the expression ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index b0d17f2510..0fe5b11b8e 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -31,6 +31,7 @@ #include "Basics/ScopeGuard.h" #include "Basics/StringBuffer.h" #include "Basics/Utf8Helper.h" +#include "Basics/VPackStringBufferAdapter.h" #include "FulltextIndex/fulltext-index.h" #include "FulltextIndex/fulltext-result.h" #include "FulltextIndex/fulltext-query.h" @@ -42,6 +43,8 @@ #include "VocBase/KeyGenerator.h" #include "VocBase/VocShaper.h" +#include +#include #include #include @@ -57,6 +60,20 @@ using VertexId = arangodb::traverser::VertexId; thread_local std::unordered_map* RegexCache = nullptr; +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transform old AQLValues to new AqlValues +/// Only temporary function +//////////////////////////////////////////////////////////////////////////////// + +static VPackFunctionParameters transformParameters( + FunctionParameters const& oldParams, arangodb::AqlTransaction* trx) { + VPackFunctionParameters newParams; + for (auto const& it : oldParams) { + newParams.emplace_back(it.first, trx, it.second); + } + return newParams; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clear the regex cache in a thread //////////////////////////////////////////////////////////////////////////////// @@ -156,21 +173,18 @@ static Json ExtractFunctionParameter(arangodb::AqlTransaction* trx, //////////////////////////////////////////////////////////////////////////////// /// @brief extract a function parameter from the arguments list /// VelocyPack variant -/// TODO: I think this could return a Slice instead. -/// Iff the AQLValue is repsonsible for the data //////////////////////////////////////////////////////////////////////////////// -static std::shared_ptr> ExtractFunctionParameterVPack( - arangodb::AqlTransaction* trx, FunctionParameters const& parameters, - size_t position, bool copy) { +static VPackSlice ExtractFunctionParameter( + arangodb::AqlTransaction* trx, VPackFunctionParameters const& parameters, + size_t position) { if (position >= parameters.size()) { // parameter out of range - VPackBuilder b; - b.add(VPackValue(VPackValueType::Null)); - return b.steal(); + VPackSlice tmp; + return tmp; } auto const& parameter = parameters[position]; - return parameter.first.toVelocyPack(trx, parameter.second, copy); + return parameter.slice(); } //////////////////////////////////////////////////////////////////////////////// @@ -249,9 +263,9 @@ static double ValueToNumber(TRI_json_t const* json, bool& isValid) { case TRI_JSON_STRING: case TRI_JSON_STRING_REFERENCE: { + std::string const str = + arangodb::basics::JsonHelper::getStringValue(json, ""); try { - std::string const str = - arangodb::basics::JsonHelper::getStringValue(json, ""); size_t behind = 0; double value = std::stod(str, &behind); while (behind < str.size()) { @@ -265,6 +279,19 @@ static double ValueToNumber(TRI_json_t const* json, bool& isValid) { isValid = true; return value; } catch (...) { + size_t behind = 0; + while (behind < str.size()) { + char c = str[behind]; + if (c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != '\f') { + isValid = false; + return 0.0; + } + ++behind; + } + // A string only containing whitespae-characters is valid and should return 0.0 + // It throws in std::stod + isValid = true; + return 0.0; } // fall-through to invalidity break; @@ -294,7 +321,6 @@ static double ValueToNumber(TRI_json_t const* json, bool& isValid) { return 0.0; } -#if 0 static double ValueToNumber(VPackSlice const& slice, bool& isValid) { if (slice.isNull()) { isValid = true; @@ -309,8 +335,12 @@ static double ValueToNumber(VPackSlice const& slice, bool& isValid) { return slice.getNumericValue(); } if (slice.isString()) { + std::string const str = slice.copyString(); try { - std::string const str = slice.copyString(); + if (str.empty()) { + isValid = true; + return 0.0; + } size_t behind = 0; double value = std::stod(str, &behind); while (behind < str.size()) { @@ -324,6 +354,19 @@ static double ValueToNumber(VPackSlice const& slice, bool& isValid) { isValid = true; return value; } catch (...) { + size_t behind = 0; + while (behind < str.size()) { + char c = str[behind]; + if (c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != '\f') { + isValid = false; + return 0.0; + } + ++behind; + } + // A string only containing whitespae-characters is valid and should return 0.0 + // It throws in std::stod + isValid = true; + return 0.0; } } if (slice.isArray()) { @@ -341,7 +384,6 @@ static double ValueToNumber(VPackSlice const& slice, bool& isValid) { isValid = false; return 0.0; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief converts a value into a boolean value @@ -365,7 +407,6 @@ static bool ValueToBoolean(TRI_json_t const* json) { return boolValue; } -#if 0 static bool ValueToBoolean(VPackSlice const& slice) { if (slice.isBoolean()) { return slice.getBoolean(); @@ -374,14 +415,13 @@ static bool ValueToBoolean(VPackSlice const& slice) { return slice.getNumericValue() != 0.0; } if (slice.isString()) { - return slice.length() != 0; + return slice.getStringLength() != 0; } if (slice.isArray() || slice.isObject()) { return true; } return false; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief extract a boolean parameter from an array @@ -400,6 +440,20 @@ static bool GetBooleanParameter(arangodb::AqlTransaction* trx, return ValueToBoolean(temp.json()); } +static bool GetBooleanParameter(arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters, + size_t startParameter, bool defaultValue) { + size_t const n = parameters.size(); + + if (startParameter >= n) { + return defaultValue; + } + + auto temp = ExtractFunctionParameter(trx, parameters, startParameter); + return ValueToBoolean(temp); +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief extract attribute names from the arguments //////////////////////////////////////////////////////////////////////////////// @@ -445,6 +499,40 @@ static void ExtractKeys(std::unordered_set& names, } } +static void ExtractKeys(std::unordered_set& names, + arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters, + size_t startParameter, char const* functionName) { + size_t const n = parameters.size(); + + for (size_t i = startParameter; i < n; ++i) { + auto param = ExtractFunctionParameter(trx, parameters, i); + + if (param.isString()) { + names.emplace(param.copyString()); + } else if (param.isNumber()) { + double number = param.getNumericValue(); + + if (std::isnan(number) || number == HUGE_VAL || number == -HUGE_VAL) { + names.emplace("null"); + } else { + char buffer[24]; + int length = fpconv_dtoa(number, &buffer[0]); + names.emplace(std::string(&buffer[0], static_cast(length))); + } + } else if (param.isArray()) { + for (auto const& v : VPackArrayIterator(param)) { + if (v.isString()) { + names.emplace(v.copyString()); + } else { + RegisterInvalidArgumentWarning(query, functionName); + } + } + } + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief append the JSON value to a string buffer //////////////////////////////////////////////////////////////////////////////// @@ -498,6 +586,34 @@ static void AppendAsString(arangodb::basics::StringBuffer& buffer, buffer.ensureNullTerminated(); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the VelocyPack value to a string buffer +/// Note: Backwards compatibility. Is different than Slice.toJson() +//////////////////////////////////////////////////////////////////////////////// + +static void AppendAsString(arangodb::basics::VPackStringBufferAdapter& buffer, + VPackSlice const& slice) { + if (slice.isString()) { + // dumping adds additional '' + buffer.append(slice.copyString()); + } else if (slice.isArray()) { + bool first = true; + for (auto const& sub : VPackArrayIterator(slice)) { + if (!first) { + buffer.append(","); + } else { + first = false; + } + AppendAsString(buffer, sub); + } + } else if (slice.isObject()) { + buffer.append("[object Object]"); + } else { + VPackDumper dumper(&buffer); + dumper.dump(slice); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief Checks if the given list contains the element //////////////////////////////////////////////////////////////////////////////// @@ -519,7 +635,6 @@ static bool ListContainsElement(Json const& list, Json const& testee) { return ListContainsElement(list, testee, unused); } -#if 0 static bool ListContainsElement(VPackSlice const& list, VPackSlice const& testee, size_t& index) { TRI_ASSERT(list.isArray()); @@ -532,14 +647,11 @@ static bool ListContainsElement(VPackSlice const& list, } return false; } -#endif -#if 0 static bool ListContainsElement(VPackSlice const& list, VPackSlice const& testee) { size_t unused; return ListContainsElement(list, testee, unused); } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief Computes the Variance of the given list. @@ -571,7 +683,6 @@ static bool Variance(Json const& values, double& value, size_t& count) { return true; } -#if 0 static bool Variance(VPackSlice const& values, double& value, size_t& count) { TRI_ASSERT(values.isArray()); value = 0.0; @@ -592,7 +703,6 @@ static bool Variance(VPackSlice const& values, double& value, size_t& count) { } return true; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief Sorts the given list of Numbers in ASC order. @@ -623,7 +733,6 @@ static bool SortNumberList(Json const& values, std::vector& result) { /// Returns false if the list contains non-number values. //////////////////////////////////////////////////////////////////////////////// -#if 0 static bool SortNumberList(VPackSlice const& values, std::vector& result) { TRI_ASSERT(values.isArray()); @@ -640,7 +749,6 @@ static bool SortNumberList(VPackSlice const& values, std::sort(result.begin(), result.end()); return true; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief Expands a shaped Json @@ -682,6 +790,65 @@ static inline Json ExpandShapedJson(VocShaper* shaper, return json; } +static inline void ExpandShapedJson( + VocShaper* shaper, CollectionNameResolver const* resolver, + TRI_voc_cid_t const& cid, TRI_doc_mptr_t const* mptr, VPackBuilder& b, + bool keepTopLevelOpen, + std::unordered_set const& forbidden) { + b.add(VPackValue(VPackValueType::Object)); + + TRI_df_marker_t const* marker = + static_cast(mptr->getDataPtr()); + + TRI_shaped_json_t shaped; + TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, marker); + std::shared_ptr tmp = TRI_VelocyPackShapedJson(shaper, &shaped); + // Copy the shaped into our local builder + for (auto const& it : VPackObjectIterator(tmp->slice())) { + std::string key = it.key.copyString(); + if (forbidden.count(key) == 0) { + b.add(it.key.copyString(), it.value); + } + } + + char const* key = TRI_EXTRACT_MARKER_KEY(marker); + std::string id(resolver->getCollectionName(cid)); + id.push_back('/'); + id.append(key); + if (forbidden.count(TRI_VOC_ATTRIBUTE_ID) == 0) { + b.add(TRI_VOC_ATTRIBUTE_ID, VPackValue(id)); + } + if (forbidden.count(TRI_VOC_ATTRIBUTE_REV) == 0) { + b.add(TRI_VOC_ATTRIBUTE_REV, + VPackValue(std::to_string(TRI_EXTRACT_MARKER_RID(marker)))); + } + if (forbidden.count(TRI_VOC_ATTRIBUTE_KEY) == 0) { + b.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(key)); + } + + if (TRI_IS_EDGE_MARKER(marker)) { + if (forbidden.count(TRI_VOC_ATTRIBUTE_FROM) == 0) { + std::string from(resolver->getCollectionNameCluster( + TRI_EXTRACT_MARKER_FROM_CID(marker))); + from.push_back('/'); + from.append(TRI_EXTRACT_MARKER_FROM_KEY(marker)); + b.add(TRI_VOC_ATTRIBUTE_FROM, VPackValue(from)); + } + + if (forbidden.count(TRI_VOC_ATTRIBUTE_TO) == 0) { + std::string to( + resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(marker))); + + to.push_back('/'); + to.append(TRI_EXTRACT_MARKER_TO_KEY(marker)); + b.add(TRI_VOC_ATTRIBUTE_TO, VPackValue(to)); + } + } + if (!keepTopLevelOpen) { + b.close(); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief Reads a document by cid and key /// Also lazy locks the collection. @@ -720,6 +887,46 @@ static Json ReadDocument(arangodb::AqlTransaction* trx, resolver, cid, &mptr); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Reads a document by cid and key +/// Also lazy locks the collection. +/// Returns null if the document does not exist +//////////////////////////////////////////////////////////////////////////////// + +static void ReadDocument(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + TRI_voc_cid_t cid, char const* key, + VPackBuilder& result) { + auto collection = trx->trxCollection(cid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, key); + + if (res != TRI_ERROR_NO_ERROR) { + result.add(VPackValue(VPackValueType::Null)); + } else { + std::unordered_set unused; + ExpandShapedJson(collection->_collection->_collection->getShaper(), + resolver, cid, &mptr, result, false, unused); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief function to filter the given list of mptr //////////////////////////////////////////////////////////////////////////////// @@ -825,6 +1032,502 @@ static void RequestEdges(arangodb::basics::Json const& vertexJson, } } +static void RequestEdges(VPackSlice const& vertexSlice, + arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + VocShaper* shaper, TRI_voc_cid_t cid, + TRI_document_collection_t* collection, + TRI_edge_direction_e direction, + arangodb::ExampleMatcher const* matcher, + bool includeVertices, VPackBuilder& result) { + std::string vertexId; + if (vertexSlice.isString()) { + vertexId = vertexSlice.copyString(); + } else if (vertexSlice.isObject()) { + vertexId = arangodb::basics::VelocyPackHelper::getStringValue(vertexSlice, + "_id", ""); + } else { + // Nothing to do. + // Return (error for illegal input is thrown outside + return; + } + + std::vector parts = + arangodb::basics::StringUtils::split(vertexId, "/"); + if (parts.size() != 2) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD, + vertexId); + } + + TRI_voc_cid_t startCid = resolver->getCollectionId(parts[0]); + if (startCid == 0) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, "'%s'", + parts[0].c_str()); + } + + char* key = const_cast(parts[1].c_str()); + std::vector edges = TRI_LookupEdgesDocumentCollection( + trx, collection, direction, startCid, key); + FilterDocuments(matcher, cid, edges); + size_t resultCount = edges.size(); + + if (includeVertices) { + for (size_t i = 0; i < resultCount; ++i) { + VPackObjectBuilder guard(&result); + result.add(VPackValue("edge")); + std::unordered_set unused; + ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result, false, unused); + char const* targetKey = nullptr; + TRI_voc_cid_t targetCid = 0; + + switch (direction) { + case TRI_EDGE_OUT: + targetKey = TRI_EXTRACT_MARKER_TO_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_TO_CID(&edges[i]); + break; + case TRI_EDGE_IN: + targetKey = TRI_EXTRACT_MARKER_FROM_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_FROM_CID(&edges[i]); + break; + case TRI_EDGE_ANY: + targetKey = TRI_EXTRACT_MARKER_TO_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_TO_CID(&edges[i]); + if (targetCid == startCid && strcmp(targetKey, key) == 0) { + targetKey = TRI_EXTRACT_MARKER_FROM_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_FROM_CID(&edges[i]); + } + break; + } + + if (targetKey == nullptr || targetCid == 0) { + // somehow invalid + continue; + } + + result.add(VPackValue("vertex")); + ReadDocument(trx, resolver, targetCid, targetKey, result); + } + } else { + for (size_t i = 0; i < resultCount; ++i) { + std::unordered_set unused; + ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result, false, unused); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to unset or keep all given names in the value. +/// Recursively iterates over sub-object and unsets or keeps their values +/// as well +//////////////////////////////////////////////////////////////////////////////// + +static void UnsetOrKeep(VPackSlice const& value, + std::unordered_set const& names, + bool unset, // true means unset, false means keep + bool recursive, VPackBuilder& result) { + TRI_ASSERT(value.isObject()); + VPackObjectBuilder b(&result); // Close the object after this function + for (auto const& entry : VPackObjectIterator(value)) { + TRI_ASSERT(entry.key.isString()); + std::string key = entry.key.copyString(); + if (!((names.find(key) == names.end()) ^ unset)) { + // not found and unset or found and keep + if (recursive && entry.value.isObject()) { + result.add(entry.key); // Add the key + UnsetOrKeep(entry.value, names, unset, recursive, result); // Adds the object + } else { + result.add(key, entry.value); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to merge given parameters +/// Works for an array of objects as first parameter or arbitrary many +/// object parameters +//////////////////////////////////////////////////////////////////////////////// + +static AqlValue$ MergeParameters(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters, + std::string const& funcName, + bool recursive) { + size_t const n = parameters.size(); + if (n == 0) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackObjectBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + // use the first argument as the preliminary result + VPackBuilder b; + auto initial = ExtractFunctionParameter(trx, parameters, 0); + if (initial.isArray() && n == 1) { + // special case: a single array parameter + try { + // Create an empty document as start point + VPackObjectBuilder guard(&b); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + // merge in all other arguments + for (auto const& it : VPackArrayIterator(initial)) { + if (!it.isObject()) { + RegisterInvalidArgumentWarning(query, "MERGE"); + b.clear(); + b.add(VPackValue(VPackValueType::Null)); + return AqlValue$(b); + } + try { + b = arangodb::basics::VelocyPackHelper::merge(b.slice(), it, false, + recursive); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + } + return AqlValue$(b); + } + + if (!initial.isObject()) { + RegisterInvalidArgumentWarning(query, "MERGE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + // merge in all other arguments + for (size_t i = 1; i < n; ++i) { + auto param = ExtractFunctionParameter(trx, parameters, i); + + if (!param.isObject()) { + RegisterInvalidArgumentWarning(query, "MERGE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + try { + b = arangodb::basics::VelocyPackHelper::merge(initial, param, false, + recursive); + initial = b.slice(); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + } + return AqlValue$(b); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms VertexId to Json +//////////////////////////////////////////////////////////////////////////////// + +static Json VertexIdToJson(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + VertexId const& id) { + auto collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), id.cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, id.key); + + if (res != TRI_ERROR_NO_ERROR) { + if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { + return Json(Json::Null); + } + THROW_ARANGO_EXCEPTION(res); + } + + return ExpandShapedJson(collection->_collection->_collection->getShaper(), + resolver, id.cid, &mptr); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms VertexId to VelocyPack +//////////////////////////////////////////////////////////////////////////////// + +static void VertexIdToVPack(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + VertexId const& id, + VPackBuilder& b) { + auto collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), id.cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, id.key); + + if (res != TRI_ERROR_NO_ERROR) { + if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { + b.add(VPackValue(VPackValueType::Null)); + return; + } + THROW_ARANGO_EXCEPTION(res); + } + + std::unordered_set unused; + ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, + id.cid, &mptr, b, false, unused); +} + + + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms VertexId to std::string +//////////////////////////////////////////////////////////////////////////////// + +static std::string VertexIdToString(CollectionNameResolver const* resolver, + VertexId const& id) { + return resolver->getCollectionName(id.cid) + "/" + std::string(id.key); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms an unordered_map to AQL json values +//////////////////////////////////////////////////////////////////////////////// + +static AqlValue VertexIdsToAqlValue(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + std::unordered_set& ids, + bool includeData = false) { + auto result = std::make_unique(Json::Array, ids.size()); + + if (includeData) { + for (auto& it : ids) { + result->add(Json(VertexIdToJson(trx, resolver, it))); + } + } else { + for (auto& it : ids) { + result->add(Json(VertexIdToString(resolver, it))); + } + } + + AqlValue v(result.get()); + result.release(); + + return v; +} + +static AqlValue$ VertexIdsToAqlValueVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, std::unordered_set& ids, + bool includeData = false) { + std::shared_ptr result = query->getSharedBuilder(); + { + VPackArrayBuilder b(result.get()); + if (includeData) { + for (auto& it : ids) { + VertexIdToVPack(trx, resolver, it, *result); + } + } else { + for (auto& it : ids) { + result->add(VPackValue(VertexIdToString(resolver, it))); + } + } + } + + return AqlValue$(result.get()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Load geoindex for collection name +//////////////////////////////////////////////////////////////////////////////// + +static arangodb::Index* getGeoIndex(arangodb::AqlTransaction* trx, + TRI_voc_cid_t const& cid, + std::string const& colName, + VocShaper*& shaper) { + auto collection = trx->trxCollection(cid); + + // ensure the collection is loaded + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION_FORMAT(res, "'%s'", colName.c_str()); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", colName.c_str()); + } + } + + auto document = trx->documentCollection(cid); + + if (document == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + + arangodb::Index* index = nullptr; + + for (auto const& idx : document->allIndexes()) { + if (idx->type() == arangodb::Index::TRI_IDX_TYPE_GEO1_INDEX || + idx->type() == arangodb::Index::TRI_IDX_TYPE_GEO2_INDEX) { + index = idx; + break; + } + } + + if (index == nullptr) { + THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_GEO_INDEX_MISSING, + colName.c_str()); + } + + if (trx->orderDitch(collection) == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + shaper = collection->_collection->_collection->getShaper(); + return index; +} + +static AqlValue$ buildGeoResult(arangodb::aql::Query* query, + GeoCoordinates* cors, VocShaper* shaper, + CollectionNameResolver const* resolver, + TRI_voc_cid_t const& cid, + std::string const& attributeName) { + if (cors == nullptr) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + size_t const nCoords = cors->length; + if (nCoords == 0) { + GeoIndex_CoordinatesFree(cors); + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + struct geo_coordinate_distance_t { + geo_coordinate_distance_t(double distance, TRI_doc_mptr_t const* mptr) + : _distance(distance), _mptr(mptr) {} + + double _distance; + TRI_doc_mptr_t const* _mptr; + }; + + std::vector distances; + + try { + distances.reserve(nCoords); + + for (size_t i = 0; i < nCoords; ++i) { + distances.emplace_back(geo_coordinate_distance_t( + cors->distances[i], + static_cast(cors->coordinates[i].data))); + } + } catch (...) { + GeoIndex_CoordinatesFree(cors); + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + GeoIndex_CoordinatesFree(cors); + + // sort result by distance + std::sort(distances.begin(), distances.end(), + [](geo_coordinate_distance_t const& left, + geo_coordinate_distance_t const& right) { + return left._distance < right._distance; + }); + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + std::unordered_set forbidden; + bool saveAttr = !attributeName.empty(); + if (saveAttr) { + forbidden.emplace(attributeName); + } + + for (auto& it : distances) { + ExpandShapedJson(shaper, resolver, cid, it._mptr, *b, + saveAttr, forbidden); + if (saveAttr) { + // The Object is Open and attributeName is not set + b->add(attributeName, VPackValue(it._distance)); + b->close(); + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief internal recursive flatten helper +//////////////////////////////////////////////////////////////////////////////// + +static void FlattenList(Json array, size_t maxDepth, size_t curDepth, + Json& result) { + size_t elementCount = array.size(); + for (size_t i = 0; i < elementCount; ++i) { + Json tmp = array.at(i); + if (tmp.isArray() && curDepth < maxDepth) { + FlattenList(tmp, maxDepth, curDepth + 1, result); + } else { + // Transfer the content of tmp into the result + result.transfer(tmp.json()); + } + } +} + +static void FlattenList(VPackSlice const& array, size_t maxDepth, + size_t curDepth, VPackBuilder& result) { + TRI_ASSERT(result.isOpenArray()); + for (auto const& tmp : VPackArrayIterator(array)) { + if (tmp.isArray() && curDepth < maxDepth) { + FlattenList(tmp, maxDepth, curDepth + 1, result); + } else { + // Copy the content of tmp into the result + result.add(tmp); + } + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief called before a query starts /// has the chance to set up any thread-local storage @@ -843,89 +1546,162 @@ void Functions::DestroyThreadContext() { ClearRegexCache(); } /// @brief function IS_NULL //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsNull(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::IsNull(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsNullVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isNull())); +#endif } -AqlValue Functions::IsNullVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { - auto const buffer = ExtractFunctionParameterVPack(trx, parameters, 0, false); - VPackSlice s(buffer->data()); - return AqlValue(new Json(s.isNull())); +AqlValue$ Functions::IsNullVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isNull())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_BOOL //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsBool(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::IsBool(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsBoolVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isBoolean())); +#endif } -AqlValue Functions::IsBoolVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { - auto const buffer = ExtractFunctionParameterVPack(trx, parameters, 0, false); - VPackSlice s(buffer->data()); - return AqlValue(new Json(s.isBoolean())); +AqlValue$ Functions::IsBoolVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isBool())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_NUMBER //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsNumber(arangodb::aql::Query*, +AqlValue Functions::IsNumber(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsNumberVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isNumber())); +#endif +} + +AqlValue$ Functions::IsNumberVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isNumber())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_STRING //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsString(arangodb::aql::Query*, +AqlValue Functions::IsString(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { + +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsStringVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isString())); +#endif +} + +AqlValue$ Functions::IsStringVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isString())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_ARRAY //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsArray(arangodb::aql::Query*, +AqlValue Functions::IsArray(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsArrayVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isArray())); +#endif +} + +AqlValue$ Functions::IsArrayVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isArray())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_OBJECT //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsObject(arangodb::aql::Query*, +AqlValue Functions::IsObject(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsObjectVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isObject())); +#endif +} + +AqlValue$ Functions::IsObjectVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isObject())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function TO_NUMBER //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToNumber(arangodb::aql::Query*, +AqlValue Functions::ToNumber(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ToNumberVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); bool isValid; @@ -935,15 +1711,38 @@ AqlValue Functions::ToNumber(arangodb::aql::Query*, return AqlValue(new Json(Json::Null)); } return AqlValue(new Json(v)); +#endif +} + +AqlValue$ Functions::ToNumberVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + + bool isValid; + double v = ValueToNumber(slice, isValid); + + std::shared_ptr b = query->getSharedBuilder(); + + if (!isValid) { + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(v)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function TO_STRING //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToString(arangodb::aql::Query*, +AqlValue Functions::ToString(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ToStringVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); @@ -960,26 +1759,64 @@ AqlValue Functions::ToString(arangodb::aql::Query*, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::ToStringVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + AppendAsString(adapter, value); + std::shared_ptr b = query->getSharedBuilder(); + try { + std::string res(buffer.begin(), buffer.length()); + b->add(VPackValue(res)); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function TO_BOOL //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToBool(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::ToBool(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ToBoolVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(ValueToBoolean(value.json()))); +#endif +} + +AqlValue$ Functions::ToBoolVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(ValueToBoolean(value))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function TO_ARRAY //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToArray(arangodb::aql::Query*, +AqlValue Functions::ToArray(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ToArrayVPack(q, trx, tmp)); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); if (value.isBoolean() || value.isNumber() || value.isString()) { @@ -1010,14 +1847,46 @@ AqlValue Functions::ToArray(arangodb::aql::Query*, // return empty array return AqlValue(new Json(Json::Array)); +#endif +} + +AqlValue$ Functions::ToArrayVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + if (value.isArray()) { + // return copy of the original array + return AqlValue$(value); + } + + std::shared_ptr result = query->getSharedBuilder(); + { + VPackArrayBuilder b(result.get()); + if (value.isBoolean() || value.isNumber() || value.isString()) { + // return array with single member + result->add(value); + } else if (value.isObject()) { + // return an array with the attribute values + for (auto const& it : VPackObjectIterator(value)) { + result->add(it.value); + } + } + // else return empty array + } + return AqlValue$(result.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function LENGTH //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::Length(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(LengthVPack(q, trx, tmp)); +#else if (!parameters.empty() && parameters[0].first.isArray()) { // shortcut! return AqlValue( @@ -1078,6 +1947,44 @@ AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx, } return AqlValue(new Json(static_cast(length))); +#endif +} + +AqlValue$ Functions::LengthVPack(arangodb::aql::Query* q, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr builder = q->getSharedBuilder(); + if (value.isArray()) { + // shortcut! + builder->add(VPackValue(static_cast(value.length()))); + return AqlValue$(builder->slice()); + } + size_t length = 0; + if (value.isNone() || value.isNull()) { + length = 0; + } else if (value.isBoolean()) { + if (value.getBoolean()) { + length = 1; + } else { + length = 0; + } + } else if (value.isNumber()) { + double tmp = value.getNumericValue(); + if (std::isnan(tmp) || !std::isfinite(tmp)) { + length = strlen("null"); + } else { + char buffer[24]; + length = static_cast(fpconv_dtoa(tmp, buffer)); + } + } else if (value.isString()) { + std::string tmp = value.copyString(); + length = TRI_CharLengthUtf8String(tmp.c_str()); + } else if (value.isObject()) { + length = static_cast(value.length()); + } + builder->add(VPackValue(static_cast(length))); + return AqlValue$(builder.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1087,6 +1994,10 @@ AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx, AqlValue Functions::First(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FirstVPack(query, trx, tmp)); +#else if (parameters.size() < 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FIRST", (int)1, @@ -1108,6 +2019,35 @@ AqlValue Functions::First(arangodb::aql::Query* query, auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(0).copy().steal(), Json::AUTOFREE); return AqlValue(j); +#endif +} + +AqlValue$ Functions::FirstVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FIRST", (int)1, + (int)1); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "FIRST", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + if (value.length() == 0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + return AqlValue$(value.at(0)); } //////////////////////////////////////////////////////////////////////////////// @@ -1117,6 +2057,10 @@ AqlValue Functions::First(arangodb::aql::Query* query, AqlValue Functions::Last(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(LastVPack(query, trx, tmp)); +#else if (parameters.size() < 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)1, @@ -1140,6 +2084,36 @@ AqlValue Functions::Last(arangodb::aql::Query* query, auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(n - 1).copy().steal(), Json::AUTOFREE); return AqlValue(j); +#endif +} + +AqlValue$ Functions::LastVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)1, + (int)1); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "LAST", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + VPackValueLength const n = value.length(); + + if (n == 0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + return AqlValue$(value.at(n-1)); } //////////////////////////////////////////////////////////////////////////////// @@ -1149,6 +2123,10 @@ AqlValue Functions::Last(arangodb::aql::Query* query, AqlValue Functions::Nth(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NthVPack(query, trx, tmp)); +#else if (parameters.size() < 2) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)2, @@ -1186,14 +2164,67 @@ AqlValue Functions::Nth(arangodb::aql::Query* query, auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(index).copy().steal(), Json::AUTOFREE); return AqlValue(j); +#endif +} + +AqlValue$ Functions::NthVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)2, + (int)2); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "NTH", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + VPackValueLength const n = value.length(); + + if (n == 0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + VPackSlice indexSlice = ExtractFunctionParameter(trx, parameters, 1); + bool isValid = true; + double numValue = ValueToNumber(indexSlice, isValid); + + if (!isValid || numValue < 0.0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + size_t index = static_cast(numValue); + + if (index >= n) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + return AqlValue$(value.at(index)); } //////////////////////////////////////////////////////////////////////////////// /// @brief function CONCAT //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::Concat(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::Concat(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ConcatVPack(query, trx, tmp)); +#else arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); size_t const n = parameters.size(); @@ -1240,6 +2271,50 @@ AqlValue Functions::Concat(arangodb::aql::Query*, arangodb::AqlTransaction* trx, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::ConcatVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + size_t const n = parameters.size(); + + for (size_t i = 0; i < n; ++i) { + auto const member = ExtractFunctionParameter(trx, parameters, i); + + if (member.isNone() || member.isNull()) { + continue; + } + + if (member.isArray()) { + // append each member individually + for (auto const& sub : VPackArrayIterator(member)) { + if (sub.isNone() || sub.isNull()) { + continue; + } + + AppendAsString(adapter, sub); + } + } else { + // convert member to a string and append + AppendAsString(adapter, member); + } + } + + // steal the StringBuffer's char* pointer so we can avoid copying data around + // multiple times + size_t length = buffer.length(); + try { + std::shared_ptr builder = query->getSharedBuilder(); + std::string res(buffer.steal(), length); + builder->add(VPackValue(std::move(res))); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1249,6 +2324,10 @@ AqlValue Functions::Concat(arangodb::aql::Query*, arangodb::AqlTransaction* trx, AqlValue Functions::Like(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(LikeVPack(query, trx, tmp)); +#else if (parameters.size() < 2) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LIKE", (int)2, @@ -1315,21 +2394,117 @@ AqlValue Functions::Like(arangodb::aql::Query* query, } return AqlValue(new Json(result)); +#endif +} + +AqlValue$ Functions::LikeVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LIKE", (int)2, + (int)3); + } + + bool const caseInsensitive = GetBooleanParameter(trx, parameters, 2, false); + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + // build pattern from parameter #1 + auto const regex = ExtractFunctionParameter(trx, parameters, 1); + AppendAsString(adapter, regex); + + size_t const length = buffer.length(); + + std::string const pattern = + BuildRegexPattern(buffer.c_str(), length, caseInsensitive); + RegexMatcher* matcher = nullptr; + + if (RegexCache != nullptr) { + auto it = RegexCache->find(pattern); + + // check regex cache + if (it != RegexCache->end()) { + matcher = (*it).second; + } + } + + if (matcher == nullptr) { + matcher = + arangodb::basics::Utf8Helper::DefaultUtf8Helper.buildMatcher(pattern); + + try { + if (RegexCache == nullptr) { + RegexCache = new std::unordered_map(); + } + // insert into cache, no matter if pattern is valid or not + RegexCache->emplace(pattern, matcher); + } catch (...) { + delete matcher; + ClearRegexCache(); + throw; + } + } + + if (matcher == nullptr) { + // compiling regular expression failed + RegisterWarning(query, "LIKE", TRI_ERROR_QUERY_INVALID_REGEX); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + // extract value + buffer.clear(); + auto const value = ExtractFunctionParameter(trx, parameters, 0); + AppendAsString(adapter, value); + + bool error = false; + bool const result = arangodb::basics::Utf8Helper::DefaultUtf8Helper.matches( + matcher, buffer.c_str(), buffer.length(), error); + + std::shared_ptr b = query->getSharedBuilder(); + if (error) { + // compiling regular expression failed + RegisterWarning(query, "LIKE", TRI_ERROR_QUERY_INVALID_REGEX); + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(result)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function PASSTHRU //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::Passthru(arangodb::aql::Query*, +AqlValue Functions::Passthru(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PassthruVPack(query, trx, tmp)); +#else if (parameters.empty()) { return AqlValue(new Json(Json::Null)); } auto json = ExtractFunctionParameter(trx, parameters, 0, true); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, json.steal())); +#endif +} + +AqlValue$ Functions::PassthruVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.empty()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue$(value); } //////////////////////////////////////////////////////////////////////////////// @@ -1339,6 +2514,10 @@ AqlValue Functions::Passthru(arangodb::aql::Query*, AqlValue Functions::Unset(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnsetVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isObject()) { @@ -1385,6 +2564,31 @@ AqlValue Functions::Unset(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnsetVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + RegisterInvalidArgumentWarning(query, "UNSET"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set names; + ExtractKeys(names, query, trx, parameters, 1, "UNSET"); + + try { + std::shared_ptr builder = query->getSharedBuilder(); + UnsetOrKeep(value, names, true, false, *builder); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1394,6 +2598,10 @@ AqlValue Functions::Unset(arangodb::aql::Query* query, AqlValue Functions::UnsetRecursive(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnsetRecursiveVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isObject()) { @@ -1457,6 +2665,31 @@ AqlValue Functions::UnsetRecursive(arangodb::aql::Query* query, TRI_json_t* result = func(value.json(), names); auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnsetRecursiveVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + RegisterInvalidArgumentWarning(query, "UNSET_RECURSIVE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set names; + ExtractKeys(names, query, trx, parameters, 1, "UNSET_RECURSIVE"); + + try { + std::shared_ptr builder = query->getSharedBuilder(); + UnsetOrKeep(value, names, true, true, *builder); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1466,6 +2699,10 @@ AqlValue Functions::UnsetRecursive(arangodb::aql::Query* query, AqlValue Functions::Keep(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(KeepVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isObject()) { @@ -1509,6 +2746,31 @@ AqlValue Functions::Keep(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::KeepVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + RegisterInvalidArgumentWarning(query, "KEEP"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set names; + ExtractKeys(names, query, trx, parameters, 1, "KEEP"); + + try { + std::shared_ptr builder = query->getSharedBuilder(); + UnsetOrKeep(value, names, false, false, *builder); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1518,6 +2780,10 @@ AqlValue Functions::Keep(arangodb::aql::Query* query, AqlValue Functions::Merge(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MergeVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n == 0) { @@ -1594,6 +2860,13 @@ AqlValue Functions::Merge(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::MergeVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + return MergeParameters(query, trx, parameters, "MERGE", false); } //////////////////////////////////////////////////////////////////////////////// @@ -1603,6 +2876,10 @@ AqlValue Functions::Merge(arangodb::aql::Query* query, AqlValue Functions::MergeRecursive(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MergeRecursiveVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n == 0) { @@ -1679,6 +2956,13 @@ AqlValue Functions::MergeRecursive(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::MergeRecursiveVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + return MergeParameters(query, trx, parameters, "MERGE_RECURSIVE", true); } //////////////////////////////////////////////////////////////////////////////// @@ -1688,6 +2972,10 @@ AqlValue Functions::MergeRecursive(arangodb::aql::Query* query, AqlValue Functions::Has(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(HasVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -1717,6 +3005,42 @@ AqlValue Functions::Has(arangodb::aql::Query* query, bool const hasAttribute = (TRI_LookupObjectJson(value.json(), p) != nullptr); return AqlValue(new Json(hasAttribute)); +#endif +} + +AqlValue$ Functions::HasVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n < 2) { + // no parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(false)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + // not an object + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(false)); + return AqlValue$(b.get()); + } + + auto name = ExtractFunctionParameter(trx, parameters, 1); + std::string p; + if (!name.isString()) { + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + AppendAsString(adapter, name); + p = std::string(buffer.c_str(), buffer.length()); + } else { + p = name.copyString(); + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(value.hasKey(p))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1726,6 +3050,10 @@ AqlValue Functions::Has(arangodb::aql::Query* query, AqlValue Functions::Attributes(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AttributesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 1) { @@ -1797,6 +3125,75 @@ AqlValue Functions::Attributes(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::AttributesVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 1) { + // no parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + if (!value.isObject()) { + // not an object + RegisterWarning(query, "ATTRIBUTES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool const removeInternal = GetBooleanParameter(trx, parameters, 1, false); + bool const doSort = GetBooleanParameter(trx, parameters, 2, false); + + TRI_ASSERT(value.isObject()); + if (value.length() == 0) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackObjectBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (doSort) { + std::set + keys; + VPackCollection::keys(value, keys); + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + for (auto const& it : keys) { + TRI_ASSERT(!it.empty()); + if (removeInternal && it.at(0) == '_') { + continue; + } + b->add(VPackValue(it)); + } + } + return AqlValue$(b.get()); + } else { + std::set keys; + VPackCollection::keys(value, keys); + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + for (auto const& it : keys) { + TRI_ASSERT(!it.empty()); + if (removeInternal && it.at(0) == '_') { + continue; + } + b->add(VPackValue(it)); + } + } + return AqlValue$(b.get()); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1806,6 +3203,10 @@ AqlValue Functions::Attributes(arangodb::aql::Query* query, AqlValue Functions::Values(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ValuesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 1) { @@ -1817,7 +3218,7 @@ AqlValue Functions::Values(arangodb::aql::Query* query, if (!value.isObject()) { // not an object - RegisterWarning(query, "ATTRIBUTES", + RegisterWarning(query, "VALUES", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); } @@ -1858,6 +3259,58 @@ AqlValue Functions::Values(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::ValuesVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 1) { + // no parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + if (!value.isObject()) { + // not an object + RegisterWarning(query, "VALUES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool const removeInternal = GetBooleanParameter(trx, parameters, 1, false); + + TRI_ASSERT(value.isObject()); + if (value.length() == 0) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackObjectBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + for (auto const& entry : VPackObjectIterator(value)) { + if (!entry.key.isString()) { + // somehow invalid + continue; + } + if (removeInternal && entry.key.copyString().at(0) == '_') { + // skip attribute + continue; + } + b->add(entry.value); + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1867,6 +3320,10 @@ AqlValue Functions::Values(arangodb::aql::Query* query, AqlValue Functions::Min(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MinVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -1903,6 +3360,37 @@ AqlValue Functions::Min(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::MinVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "MIN", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice minValue; + for (auto const& it : VPackArrayIterator(value)) { + if (it.isNull()) { + continue; + } + if (minValue.isNone() || arangodb::basics::VelocyPackHelper::compare(it, minValue, true) < 0) { + minValue = it; + } + } + if (minValue.isNone()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + return AqlValue$(minValue); } //////////////////////////////////////////////////////////////////////////////// @@ -1912,6 +3400,10 @@ AqlValue Functions::Min(arangodb::aql::Query* query, AqlValue Functions::Max(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MaxVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -1949,6 +3441,33 @@ AqlValue Functions::Max(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::MaxVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "MAX", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + VPackSlice maxValue; + for (auto const& it : VPackArrayIterator(value)) { + if (maxValue.isNone() || arangodb::basics::VelocyPackHelper::compare(it, maxValue, true) > 0) { + maxValue = it; + } + } + if (maxValue.isNone()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + return AqlValue$(maxValue); } //////////////////////////////////////////////////////////////////////////////// @@ -1958,6 +3477,10 @@ AqlValue Functions::Max(arangodb::aql::Query* query, AqlValue Functions::Sum(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(SumVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -1997,6 +3520,45 @@ AqlValue Functions::Sum(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::SumVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "SUM", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double sum = 0.0; + for (auto const& it : VPackArrayIterator(value)) { + if (it.isNull()) { + continue; + } + if (!it.isNumber()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + double const number = it.getNumericValue(); + + if (!std::isnan(number) && number != HUGE_VAL && number != -HUGE_VAL) { + sum += number; + } + } + std::shared_ptr b = query->getSharedBuilder(); + if (!std::isnan(sum) && sum != HUGE_VAL && sum != -HUGE_VAL) { + b->add(VPackValue(sum)); + } else { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2006,6 +3568,10 @@ AqlValue Functions::Sum(arangodb::aql::Query* query, AqlValue Functions::Average(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AverageVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -2046,6 +3612,51 @@ AqlValue Functions::Average(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::AverageVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "AVERAGE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double sum = 0.0; + size_t count = 0; + for (auto const& v : VPackArrayIterator(value)) { + if (v.isNull()) { + continue; + } + if (!v.isNumber()) { + RegisterWarning(query, "AVERAGE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + // got a numeric value + double const number = v.getNumericValue(); + + if (!std::isnan(number) && number != HUGE_VAL && number != -HUGE_VAL) { + sum += number; + ++count; + } + } + + std::shared_ptr b = query->getSharedBuilder(); + if (count > 0 && !std::isnan(sum) && sum != HUGE_VAL && sum != -HUGE_VAL) { + b->add(VPackValue(sum / static_cast(count))); + } else { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2077,6 +3688,34 @@ AqlValue Functions::Md5(arangodb::aql::Query* query, return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, hex, 32)); } +AqlValue$ Functions::Md5VPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + AppendAsString(adapter, value); + + // create md5 + char hash[17]; + char* p = &hash[0]; + size_t length; + + arangodb::rest::SslInterface::sslMD5(buffer.c_str(), buffer.length(), p, + length); + + // as hex + char hex[33]; + p = &hex[0]; + + arangodb::rest::SslInterface::sslHEX(hash, 16, p, length); + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(std::string(hex, 32))); + return AqlValue$(b.get()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief function SHA1 //////////////////////////////////////////////////////////////////////////////// @@ -2084,6 +3723,10 @@ AqlValue Functions::Md5(arangodb::aql::Query* query, AqlValue Functions::Sha1(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(Sha1VPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); @@ -2104,6 +3747,36 @@ AqlValue Functions::Sha1(arangodb::aql::Query* query, arangodb::rest::SslInterface::sslHEX(hash, 20, p, length); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, hex, 40)); +#endif +} + +AqlValue$ Functions::Sha1VPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + AppendAsString(adapter, value); + + // create sha1 + char hash[21]; + char* p = &hash[0]; + size_t length; + + arangodb::rest::SslInterface::sslSHA1(buffer.c_str(), buffer.length(), p, + length); + + // as hex + char hex[41]; + p = &hex[0]; + + arangodb::rest::SslInterface::sslHEX(hash, 20, p, length); + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(std::string(hex, 40))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2113,6 +3786,10 @@ AqlValue Functions::Sha1(arangodb::aql::Query* query, AqlValue Functions::Unique(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UniqueVPack(query, trx, tmp)); +#else if (parameters.size() != 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNIQUE", (int)1, @@ -2160,6 +3837,50 @@ AqlValue Functions::Unique(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UniqueVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNIQUE", (int)1, + (int)1); + } + + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "UNIQUE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set + values(512, arangodb::basics::VelocyPackHelper::VPackHash(), + arangodb::basics::VelocyPackHelper::VPackEqual()); + + for (auto const& s : VPackArrayIterator(value)) { + if (!s.isNone()) { + values.emplace(s); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : values) { + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2169,6 +3890,10 @@ AqlValue Functions::Unique(arangodb::aql::Query* query, AqlValue Functions::SortedUnique(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(SortedUniqueVPack(query, trx, tmp)); +#else if (parameters.size() != 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SORTED_UNIQUE", @@ -2219,6 +3944,45 @@ AqlValue Functions::SortedUnique(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::SortedUniqueVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SORTED_UNIQUE", + (int)1, (int)1); + } + + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + // this is an internal function - do NOT issue a warning here + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::set> values; + for (auto const& it : VPackArrayIterator(value)) { + if (!it.isNone()) { + values.insert(it); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : values) { + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2228,6 +3992,10 @@ AqlValue Functions::SortedUnique(arangodb::aql::Query* query, AqlValue Functions::Union(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnionVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -2283,6 +4051,57 @@ AqlValue Functions::Union(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnionVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNION", (int)2, + (int)Function::MaxArguments); + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (size_t i = 0; i < n; ++i) { + auto value = ExtractFunctionParameter(trx, parameters, i); + + if (!value.isArray()) { + // not an array + RegisterInvalidArgumentWarning(query, "UNION"); + b->clear(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + // this passes ownership for the JSON contens into result + for (auto const& it : VPackArrayIterator(value)) { + b->add(it); + TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + } + } + } catch (arangodb::basics::Exception const& e) { + // Rethrow arangodb Errors + throw e; + } catch (std::exception const& e) { + // All other exceptions are OUT_OF_MEMORY + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + TRI_IF_FAILURE("AqlFunctions::OutOfMemory3") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2292,6 +4111,10 @@ AqlValue Functions::Union(arangodb::aql::Query* query, AqlValue Functions::UnionDistinct(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnionDistinctVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -2373,6 +4196,68 @@ AqlValue Functions::UnionDistinct(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnionDistinctVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNION_DISTINCT", + (int)2, (int)Function::MaxArguments); + } + + std::unordered_set + values(512, arangodb::basics::VelocyPackHelper::VPackHash(), + arangodb::basics::VelocyPackHelper::VPackEqual()); + + + for (size_t i = 0; i < n; ++i) { + auto value = ExtractFunctionParameter(trx, parameters, i); + + if (!value.isArray()) { + // not an array + RegisterInvalidArgumentWarning(query, "UNION_DISTINCT"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + for (auto const& v : VPackArrayIterator(value)) { + if (values.find(v) == values.end()) { + TRI_IF_FAILURE("AqlFunctions::OutOfMemory1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + values.emplace(v); + } + } + } + + std::shared_ptr b = query->getSharedBuilder(); + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : values) { + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory3") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2382,6 +4267,10 @@ AqlValue Functions::UnionDistinct(arangodb::aql::Query* query, AqlValue Functions::Intersection(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IntersectionVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -2488,81 +4377,79 @@ AqlValue Functions::Intersection(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif } -//////////////////////////////////////////////////////////////////////////////// -/// @brief Transforms VertexId to Json -//////////////////////////////////////////////////////////////////////////////// -static Json VertexIdToJson(arangodb::AqlTransaction* trx, - CollectionNameResolver const* resolver, - VertexId const& id) { - auto collection = trx->trxCollection(id.cid); +AqlValue$ Functions::IntersectionVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); - if (collection == nullptr) { - int res = TRI_AddCollectionTransaction(trx->getInternals(), id.cid, - TRI_TRANSACTION_READ, - trx->nestingLevel(), true, true); - if (res != TRI_ERROR_NO_ERROR) { - THROW_ARANGO_EXCEPTION(res); + if (n < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "INTERSECTION", + (int)2, (int)Function::MaxArguments); + } + + std::unordered_map + values(512, arangodb::basics::VelocyPackHelper::VPackHash(), + arangodb::basics::VelocyPackHelper::VPackEqual()); + + std::shared_ptr b = query->getSharedBuilder(); + + for (size_t i = 0; i < n; ++i) { + auto value = ExtractFunctionParameter(trx, parameters, i); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "INTERSECTION", TRI_ERROR_QUERY_ARRAY_EXPECTED); + b->clear(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } + + for (auto const& it : VPackArrayIterator(value)) { + if (i == 0) { + // round one - TRI_EnsureCollectionsTransaction(trx->getInternals()); - collection = trx->trxCollection(id.cid); + TRI_IF_FAILURE("AqlFunctions::OutOfMemory1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } - if (collection == nullptr) { - THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, - "collection is a nullptr"); + values.emplace(it, 1); + } else { + // check if we have seen the same element before + auto found = values.find(it); + if (found != values.end()) { + // already seen + TRI_ASSERT((*found).second > 0); + ++(found->second); + } + } } } - TRI_doc_mptr_copy_t mptr; - int res = trx->readSingle(collection, &mptr, id.key); - - if (res != TRI_ERROR_NO_ERROR) { - if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { - return Json(Json::Null); - } - THROW_ARANGO_EXCEPTION(res); + TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } - return ExpandShapedJson(collection->_collection->_collection->getShaper(), - resolver, id.cid, &mptr); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Transforms VertexId to std::string -//////////////////////////////////////////////////////////////////////////////// - -static std::string VertexIdToString(CollectionNameResolver const* resolver, - VertexId const& id) { - return resolver->getCollectionName(id.cid) + "/" + std::string(id.key); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Transforms an unordered_map to AQL json values -//////////////////////////////////////////////////////////////////////////////// - -static AqlValue VertexIdsToAqlValue(arangodb::AqlTransaction* trx, - CollectionNameResolver const* resolver, - std::unordered_set& ids, - bool includeData = false) { - auto result = std::make_unique(Json::Array, ids.size()); - - if (includeData) { - for (auto& it : ids) { - result->add(Json(VertexIdToJson(trx, resolver, it))); - } - } else { - for (auto& it : ids) { - result->add(Json(VertexIdToString(resolver, it))); + { + VPackArrayBuilder guard(b.get()); + for (auto const& it : values) { + if (it.second == n) { + b->add(it.first); + } } } + values.clear(); - AqlValue v(result.get()); - result.release(); - - return v; + TRI_IF_FAILURE("AqlFunctions::OutOfMemory3") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2572,6 +4459,10 @@ static AqlValue VertexIdsToAqlValue(arangodb::AqlTransaction* trx, AqlValue Functions::Neighbors(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NeighborsVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); arangodb::traverser::NeighborsOptions opts; @@ -2764,6 +4655,192 @@ AqlValue Functions::Neighbors(arangodb::aql::Query* query, TRI_RunNeighborsSearch(edgeCollectionInfos, opts, neighbors); return VertexIdsToAqlValue(trx, resolver, neighbors, includeData); +#endif +} + +AqlValue$ Functions::NeighborsVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + arangodb::traverser::NeighborsOptions opts; + + if (n < 4 || n > 6) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS", (int)4, + (int)6); + } + + auto resolver = trx->resolver(); + + VPackSlice vertexCol = ExtractFunctionParameter(trx, parameters, 0); + + if (!vertexCol.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + std::string vColName = vertexCol.copyString(); + + VPackSlice edgeCol = ExtractFunctionParameter(trx, parameters, 1); + if (!edgeCol.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + std::string eColName = edgeCol.copyString(); + + VPackSlice vertexInfo = ExtractFunctionParameter(trx, parameters, 2); + std::string vertexId; + bool splitCollection = false; + if (vertexInfo.isString()) { + vertexId = vertexInfo.copyString(); + if (vertexId.find("/") != std::string::npos) { + splitCollection = true; + } + } else if (vertexInfo.isObject()) { + if (!vertexInfo.hasKey("_id")) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + VPackSlice idSlice = vertexInfo.get("_id"); + if (!idSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + vertexId = idSlice.copyString(); + splitCollection = true; + } else { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + + if (splitCollection) { + size_t split; + char const* str = vertexId.c_str(); + + if (!TRI_ValidateDocumentIdKeyGenerator(str, &split)) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD); + } + + std::string const collectionName = vertexId.substr(0, split); + if (collectionName.compare(vColName) != 0) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_GRAPH_INVALID_PARAMETER, + "specified vertex collection '%s' does " + "not match start vertex collection '%s'", + vColName.c_str(), collectionName.c_str()); + } + auto coli = resolver->getCollectionStruct(collectionName); + + if (coli == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", collectionName.c_str()); + } + + VertexId v(coli->_cid, const_cast(str + split + 1)); + opts.start = v; + } else { + VertexId v(resolver->getCollectionId(vColName), vertexId.c_str()); + opts.start = v; + } + + VPackSlice direction = ExtractFunctionParameter(trx, parameters, 3); + if (!direction.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + { + std::string const dir = direction.copyString(); + if (dir.compare("outbound") == 0) { + opts.direction = TRI_EDGE_OUT; + } else if (dir.compare("inbound") == 0) { + opts.direction = TRI_EDGE_IN; + } else if (dir.compare("any") == 0) { + opts.direction = TRI_EDGE_ANY; + } else { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + } + + bool includeData = false; + + if (n > 5) { + auto options = ExtractFunctionParameter(trx, parameters, 5); + if (!options.isObject()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + includeData = arangodb::basics::VelocyPackHelper::getBooleanValue( + options, "includeData", false); + opts.minDepth = + arangodb::basics::VelocyPackHelper::getNumericValue( + options, "minDepth", 1); + if (opts.minDepth == 0) { + opts.maxDepth = + arangodb::basics::VelocyPackHelper::getNumericValue( + options, "maxDepth", 1); + } else { + opts.maxDepth = + arangodb::basics::VelocyPackHelper::getNumericValue( + options, "maxDepth", opts.minDepth); + } + } + + TRI_voc_cid_t eCid = resolver->getCollectionId(eColName); + + { + // ensure the collection is loaded + auto collection = trx->trxCollection(eCid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), eCid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(eCid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + } + + // Function to return constant distance + auto wc = [](TRI_doc_mptr_copy_t&) -> double { return 1; }; + + auto eci = std::make_unique( + trx, eCid, trx->documentCollection(eCid), wc); + TRI_IF_FAILURE("EdgeCollectionInfoOOM1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + if (n > 4) { + auto edgeExamples = ExtractFunctionParameter(trx, parameters, 4); + if (!(edgeExamples.isArray() && edgeExamples.length() == 0)) { + opts.addEdgeFilter(edgeExamples, eci->getShaper(), eCid, resolver); + } + } + + std::vector edgeCollectionInfos; + arangodb::basics::ScopeGuard guard{[]() -> void {}, + [&edgeCollectionInfos]() -> void { + for (auto& p : edgeCollectionInfos) { + delete p; + } + }}; + edgeCollectionInfos.emplace_back(eci.get()); + eci.release(); + TRI_IF_FAILURE("EdgeCollectionInfoOOM2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + std::unordered_set neighbors; + TRI_RunNeighborsSearch(edgeCollectionInfos, opts, neighbors); + + return VertexIdsToAqlValueVPack(query, trx, resolver, neighbors, includeData); } //////////////////////////////////////////////////////////////////////////////// @@ -2773,6 +4850,10 @@ AqlValue Functions::Neighbors(arangodb::aql::Query* query, AqlValue Functions::Near(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NearVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 3 || n > 5) { @@ -2943,6 +5024,79 @@ AqlValue Functions::Near(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, array.steal())); +#endif +} + +AqlValue$ Functions::NearVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 3 || n > 5) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEAR", (int)3, + (int)5); + } + + auto resolver = trx->resolver(); + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice latitude = ExtractFunctionParameter(trx, parameters, 1); + VPackSlice longitude = ExtractFunctionParameter(trx, parameters, 2); + + if (!latitude.isNumber() || !longitude.isNumber()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + + // extract limit + int64_t limitValue = 100; + + if (n > 3) { + VPackSlice limit = ExtractFunctionParameter(trx, parameters, 3); + + if (limit.isNumber()) { + limitValue = limit.getNumericValue(); + } else if (!limit.isNull()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + } + + std::string attributeName; + if (n > 4) { + // have a distance attribute + VPackSlice distanceAttribute = ExtractFunctionParameter(trx, parameters, 4); + + if (!distanceAttribute.isNull() && !distanceAttribute.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + + if (distanceAttribute.isString()) { + attributeName = distanceAttribute.copyString(); + } + } + + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + VocShaper* shaper = nullptr; + arangodb::Index* index = getGeoIndex(trx, cid, colName, shaper); + + TRI_ASSERT(index != nullptr); + TRI_ASSERT(shaper != nullptr); + + GeoCoordinates* cors = static_cast(index)->nearQuery( + trx, latitude.getNumericValue(), + longitude.getNumericValue(), limitValue); + + return buildGeoResult(query, cors, shaper, resolver, cid, attributeName); } //////////////////////////////////////////////////////////////////////////////// @@ -2952,6 +5106,10 @@ AqlValue Functions::Near(arangodb::aql::Query* query, AqlValue Functions::Within(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(WithinVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 4 || n > 5) { @@ -3108,24 +5266,67 @@ AqlValue Functions::Within(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, array.steal())); +#endif } -//////////////////////////////////////////////////////////////////////////////// -/// @brief internal recursive flatten helper -//////////////////////////////////////////////////////////////////////////////// +AqlValue$ Functions::WithinVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); -static void FlattenList(Json array, size_t maxDepth, size_t curDepth, - Json& result) { - size_t elementCount = array.size(); - for (size_t i = 0; i < elementCount; ++i) { - Json tmp = array.at(i); - if (tmp.isArray() && curDepth < maxDepth) { - FlattenList(tmp, maxDepth, curDepth + 1, result); - } else { - // Transfer the content of tmp into the result - result.transfer(tmp.json()); + if (n < 4 || n > 5) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "WITHIN", (int)4, + (int)5); + } + + auto resolver = trx->resolver(); + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "WITHIN"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice latitude = ExtractFunctionParameter(trx, parameters, 1); + VPackSlice longitude = ExtractFunctionParameter(trx, parameters, 2); + VPackSlice radius = ExtractFunctionParameter(trx, parameters, 3); + + if (!latitude.isNumber() || !longitude.isNumber() || !radius.isNumber()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "WITHIN"); + } + + std::string attributeName; + if (n > 4) { + // have a distance attribute + VPackSlice distanceAttribute = ExtractFunctionParameter(trx, parameters, 4); + + if (!distanceAttribute.isNull() && !distanceAttribute.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "WITHIN"); + } + + if (distanceAttribute.isString()) { + attributeName = distanceAttribute.copyString(); } } + + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + VocShaper* shaper = nullptr; + arangodb::Index* index = getGeoIndex(trx, cid, colName, shaper); + + TRI_ASSERT(index != nullptr); + TRI_ASSERT(shaper != nullptr); + + GeoCoordinates* cors = static_cast(index)->withinQuery( + trx, latitude.getNumericValue(), + longitude.getNumericValue(), radius.getNumericValue()); + + return buildGeoResult(query, cors, shaper, resolver, cid, attributeName); } //////////////////////////////////////////////////////////////////////////////// @@ -3135,6 +5336,10 @@ static void FlattenList(Json array, size_t maxDepth, size_t curDepth, AqlValue Functions::Flatten(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FlattenVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n == 0 || n > 2) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -3164,6 +5369,48 @@ AqlValue Functions::Flatten(arangodb::aql::Query* query, FlattenList(listJson.copy(), maxDepth, 0, result); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::FlattenVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n == 0 || n > 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FLATTEN", (int)1, + (int)2); + } + + VPackSlice listSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!listSlice.isArray()) { + RegisterWarning(query, "FLATTEN", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + size_t maxDepth = 1; + if (n == 2) { + VPackSlice maxDepthSlice = ExtractFunctionParameter(trx, parameters, 1); + bool isValid = true; + double tmpMaxDepth = ValueToNumber(maxDepthSlice, isValid); + if (!isValid || tmpMaxDepth < 1) { + maxDepth = 1; + } else { + maxDepth = static_cast(tmpMaxDepth); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + FlattenList(listSlice, maxDepth, 0, *b); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3173,6 +5420,10 @@ AqlValue Functions::Flatten(arangodb::aql::Query* query, AqlValue Functions::Zip(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ZipVPack(query, trx, tmp)); +#else if (parameters.size() != 2) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ZIP", (int)2, @@ -3199,6 +5450,48 @@ AqlValue Functions::Zip(arangodb::aql::Query* query, result.set(buffer.c_str(), valuesJson.at(i).copy().steal()); } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::ZipVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ZIP", (int)2, + (int)2); + } + + VPackSlice keysSlice = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice valuesSlice = ExtractFunctionParameter(trx, parameters, 1); + + if (!keysSlice.isArray() || !valuesSlice.isArray() || + keysSlice.length() != valuesSlice.length()) { + RegisterWarning(query, "ZIP", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackValueLength n = keysSlice.length(); + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackObjectBuilder guard(b.get()); + + // Buffer will temporarily hold the keys + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + for (VPackValueLength i = 0; i < n; ++i) { + buffer.reset(); + AppendAsString(adapter, keysSlice.at(i)); + b->add(std::string(buffer.c_str(), buffer.length()), valuesSlice.at(i)); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3208,6 +5501,10 @@ AqlValue Functions::Zip(arangodb::aql::Query* query, AqlValue Functions::ParseIdentifier(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ParseIdentifierVPack(query, trx, tmp)); +#else if (parameters.size() != 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PARSE_IDENTIFIER", @@ -3238,6 +5535,48 @@ AqlValue Functions::ParseIdentifier(arangodb::aql::Query* query, RegisterWarning(query, "PARSE_IDENTIFIER", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::ParseIdentifierVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PARSE_IDENTIFIER", + (int)1, (int)1); + } + + VPackSlice value = ExtractFunctionParameter(trx, parameters, 0); + std::string identifier; + if (value.isObject() && value.hasKey(TRI_VOC_ATTRIBUTE_ID)) { + identifier = arangodb::basics::VelocyPackHelper::getStringValue( + value, TRI_VOC_ATTRIBUTE_ID, ""); + } else if (value.isString()) { + identifier = value.copyString(); + } + + if (!identifier.empty()) { + std::vector parts = + arangodb::basics::StringUtils::split(identifier, "/"); + if (parts.size() == 2) { + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackObjectBuilder guard(b.get()); + b->add("collection", VPackValue(parts[0])); + b->add("key", VPackValue(parts[1])); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); + } + } + + RegisterWarning(query, "PARSE_IDENTIFIER", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3247,6 +5586,10 @@ AqlValue Functions::ParseIdentifier(arangodb::aql::Query* query, AqlValue Functions::Minus(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MinusVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -3297,6 +5640,70 @@ AqlValue Functions::Minus(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::MinusVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 2) { + // The max number is arbitrary + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "MINUS", (int)2, + (int)99999); + } + VPackSlice baseArray = ExtractFunctionParameter(trx, parameters, 0); + + if (!baseArray.isArray()) { + RegisterWarning(query, "MINUS", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_map contains; + contains.reserve(n); + + // Fill the original map + for (size_t i = 0; i < baseArray.length(); ++i) { + contains.emplace(baseArray.at(i).toJson(), i); + } + + // Iterate through all following parameters and delete found elements from the + // map + for (size_t k = 1; k < n; ++k) { + VPackSlice nextArray = ExtractFunctionParameter(trx, parameters, k); + if (!nextArray.isArray()) { + RegisterWarning(query, "MINUS", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + for (auto const& searchSlice : VPackArrayIterator(nextArray)) { + std::string search = searchSlice.toJson(); + auto find = contains.find(search); + if (find != contains.end()) { + contains.erase(find); + } + } + } + + // We ommit the normalize part from js, cannot occur here + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : contains) { + b->add(baseArray.at(it.second)); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } static void RegisterCollectionInTransaction( @@ -3407,6 +5814,90 @@ static Json getDocumentByIdentifier(arangodb::AqlTransaction* trx, resolver, cid, &mptr); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to get a document by it's identifier +/// The collection has to be locked by the transaction before +//////////////////////////////////////////////////////////////////////////////// + +static void getDocumentByIdentifier(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + TRI_transaction_collection_t* collection, + TRI_voc_cid_t const& cid, + std::string const& collectionName, + std::string const& identifier, + VPackBuilder& result) { + std::vector parts = + arangodb::basics::StringUtils::split(identifier, "/"); + + TRI_doc_mptr_copy_t mptr; + if (parts.size() == 1) { + int res = trx->readSingle(collection, &mptr, parts[0]); + if (res != TRI_ERROR_NO_ERROR) { + return; + } + } else if (parts.size() == 2) { + if (parts[0] != collectionName) { + // Reqesting an _id that cannot be stored in this collection + return; + } + int res = trx->readSingle(collection, &mptr, parts[1]); + if (res != TRI_ERROR_NO_ERROR) { + return; + } + } else { + return; + } + + std::unordered_set unused; + ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, + cid, &mptr, result, false, unused); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to get a document by its _id +/// This function will lazy read-lock the collection. +/// this function will not throw if the document or the collection cannot be +/// found +//////////////////////////////////////////////////////////////////////////////// + +static void getDocumentByIdentifier(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + std::string const& identifier, + VPackBuilder& result) { + std::vector parts = + arangodb::basics::StringUtils::split(identifier, "/"); + + if (parts.size() != 2) { + return; + } + std::string collectionName = parts[0]; + TRI_transaction_collection_t* collection = nullptr; + TRI_voc_cid_t cid = 0; + try { + RegisterCollectionInTransaction(trx, collectionName, cid, collection); + } catch (arangodb::basics::Exception const& ex) { + // don't throw if collection is not found + if (ex.code() == TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) { + return; + } + throw; + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, parts[1]); + + if (res != TRI_ERROR_NO_ERROR) { + return; + } + + std::unordered_set unused; + ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, + cid, &mptr, result, false, unused); +} + + + + //////////////////////////////////////////////////////////////////////////////// /// @brief function Document //////////////////////////////////////////////////////////////////////////////// @@ -3414,6 +5905,10 @@ static Json getDocumentByIdentifier(arangodb::AqlTransaction* trx, AqlValue Functions::Document(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(DocumentVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 1 || 2 < n) { @@ -3512,6 +6007,106 @@ AqlValue Functions::Document(arangodb::aql::Query* query, } // Id has invalid format return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::DocumentVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 1 || 2 < n) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "DOCUMENT", (int)1, + (int)2); + } + + auto resolver = trx->resolver(); + if (n == 1) { + VPackSlice id = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + if (id.isString()) { + std::string identifier = id.copyString(); + getDocumentByIdentifier(trx, resolver, identifier, *b); + if (b->isEmpty()) { + // not found + b->add(VPackValue(VPackValueType::Null)); + } + } else if (id.isArray()) { + VPackArrayBuilder guard(b.get()); + for (auto const& next : VPackArrayIterator(id)) { + try { + if (next.isString()) { + std::string identifier = next.copyString(); + getDocumentByIdentifier(trx, resolver, identifier, *b); + } + } catch (arangodb::basics::Exception const&) { + // Ignore all ArangoDB exceptions here + } + } + } else { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); + } + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + std::string collectionName = collectionSlice.copyString(); + + TRI_transaction_collection_t* collection = nullptr; + TRI_voc_cid_t cid; + bool notFound = false; + + try { + RegisterCollectionInTransaction(trx, collectionName, cid, collection); + } catch (arangodb::basics::Exception const& ex) { + // don't throw if collection is not found + if (ex.code() != TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) { + throw; + } + notFound = true; + } + + VPackSlice id = ExtractFunctionParameter(trx, parameters, 1); + if (id.isString()) { + if (notFound) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::shared_ptr b = query->getSharedBuilder(); + std::string identifier = id.copyString(); + getDocumentByIdentifier(trx, resolver, collection, cid, collectionName, identifier, *b); + if (b->isEmpty()) { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); + } else if (id.isArray()) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + if (!notFound) { + for (auto const& next : VPackArrayIterator(id)) { + try { + if (next.isString()) { + std::string identifier = next.copyString(); + getDocumentByIdentifier(trx, resolver, collection, cid, collectionName, identifier, *b); + } + } catch (arangodb::basics::Exception const&) { + // Ignore all ArangoDB exceptions here + } + } + } + } + return AqlValue$(b.get()); + } + // Id has invalid format + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3521,6 +6116,10 @@ AqlValue Functions::Document(arangodb::aql::Query* query, AqlValue Functions::Edges(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(EdgesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 3 || 5 < n) { @@ -3665,6 +6264,132 @@ AqlValue Functions::Edges(arangodb::aql::Query* query, includeVertices, result); } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::EdgesVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 3 || 5 < n) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "EDGES", (int)3, + (int)5); + } + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + std::string collectionName = collectionSlice.copyString(); + + TRI_transaction_collection_t* collection = nullptr; + TRI_voc_cid_t cid; + RegisterCollectionInTransaction(trx, collectionName, cid, collection); + if (collection->_collection->_type != TRI_COL_TYPE_EDGE) { + RegisterWarning(query, "EDGES", TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice vertexSlice = ExtractFunctionParameter(trx, parameters, 1); + if (!vertexSlice.isArray() && !vertexSlice.isString() && !vertexSlice.isObject()) { + // Invalid Start vertex + // Early Abort before parsing other parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice directionSlice = ExtractFunctionParameter(trx, parameters, 2); + if (!directionSlice.isString()) { + RegisterWarning(query, "EDGES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::string dirString = directionSlice.copyString(); + // transform String to lower case + std::transform(dirString.begin(), dirString.end(), dirString.begin(), + ::tolower); + + TRI_edge_direction_e direction; + + if (dirString == "inbound") { + direction = TRI_EDGE_IN; + } else if (dirString == "outbound") { + direction = TRI_EDGE_OUT; + } else if (dirString == "any") { + direction = TRI_EDGE_ANY; + } else { + RegisterWarning(query, "EDGES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto resolver = trx->resolver(); + + auto shaper = collection->_collection->_collection->getShaper(); + std::unique_ptr matcher; + + if (n > 3) { + // We might have examples + VPackSlice exampleSlice = ExtractFunctionParameter(trx, parameters, 3); + if ((exampleSlice.isArray() && exampleSlice.length() != 0)|| exampleSlice.isObject()) { + try { + matcher.reset( + new arangodb::ExampleMatcher(exampleSlice, shaper, resolver, false)); + } catch (arangodb::basics::Exception const& e) { + if (e.code() != TRI_RESULT_ELEMENT_NOT_FOUND) { + throw; + } + // We can never fulfill this filter! + // RETURN empty Array + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + } + } + + bool includeVertices = false; + + if (n == 5) { + // We have options + VPackSlice options = ExtractFunctionParameter(trx, parameters, 4); + if (options.isObject()) { + includeVertices = arangodb::basics::VelocyPackHelper::getBooleanValue( + options, "includeVertices", false); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + if (vertexSlice.isArray()) { + for (auto const& v : VPackArrayIterator(vertexSlice)) { + try { + RequestEdges(v, trx, resolver, shaper, cid, + collection->_collection->_collection, direction, + matcher.get(), includeVertices, *b); + } catch (...) { + // Errors in Array are simply ignored + } + } + } else { + RequestEdges(vertexSlice, trx, resolver, shaper, cid, + collection->_collection->_collection, direction, + matcher.get(), includeVertices, *b); + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3672,8 +6397,12 @@ AqlValue Functions::Edges(arangodb::aql::Query* query, //////////////////////////////////////////////////////////////////////////////// AqlValue Functions::Round(arangodb::aql::Query* query, - arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { + arangodb::AqlTransaction* trx, + FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RoundVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -3688,6 +6417,29 @@ AqlValue Functions::Round(arangodb::aql::Query* query, double input = TRI_ToDoubleJson(inputJson.json(), unused); input = floor(input + 0.5); // Rounds down for < x.4999 and up for > x.50000 return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::RoundVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ROUND", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = floor(input + 0.5); // Rounds down for < x.4999 and up for > x.50000 + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3697,6 +6449,10 @@ AqlValue Functions::Round(arangodb::aql::Query* query, AqlValue Functions::Abs(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AbsVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -3711,6 +6467,29 @@ AqlValue Functions::Abs(arangodb::aql::Query* query, double input = TRI_ToDoubleJson(inputJson.json(), unused); input = std::abs(input); return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::AbsVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ABS", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = std::abs(input); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3720,6 +6499,10 @@ AqlValue Functions::Abs(arangodb::aql::Query* query, AqlValue Functions::Ceil(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(CeilVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -3734,6 +6517,29 @@ AqlValue Functions::Ceil(arangodb::aql::Query* query, double input = TRI_ToDoubleJson(inputJson.json(), unused); input = ceil(input); return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::CeilVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "CEIL", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = ceil(input); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3743,6 +6549,10 @@ AqlValue Functions::Ceil(arangodb::aql::Query* query, AqlValue Functions::Floor(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FloorVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -3757,6 +6567,29 @@ AqlValue Functions::Floor(arangodb::aql::Query* query, double input = TRI_ToDoubleJson(inputJson.json(), unused); input = floor(input); return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::FloorVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FLOOR", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = floor(input); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3766,6 +6599,10 @@ AqlValue Functions::Floor(arangodb::aql::Query* query, AqlValue Functions::Sqrt(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(SqrtVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -3783,6 +6620,32 @@ AqlValue Functions::Sqrt(arangodb::aql::Query* query, return AqlValue(new Json(Json::Null)); } return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::SqrtVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SQRT", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + input = sqrt(input); + std::shared_ptr b = query->getSharedBuilder(); + if (std::isnan(input)) { + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(input)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3792,6 +6655,10 @@ AqlValue Functions::Sqrt(arangodb::aql::Query* query, AqlValue Functions::Pow(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PowVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2) { @@ -3811,6 +6678,34 @@ AqlValue Functions::Pow(arangodb::aql::Query* query, return AqlValue(new Json(Json::Null)); } return AqlValue(new Json(base)); +#endif +} + +AqlValue$ Functions::PowVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "POW", (int)2, + (int)2); + } + + VPackSlice baseSlice = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice expSlice = ExtractFunctionParameter(trx, parameters, 1); + + bool unused = false; + double base = arangodb::basics::VelocyPackHelper::toDouble(baseSlice, unused); + double exp = arangodb::basics::VelocyPackHelper::toDouble(expSlice, unused); + base = pow(base, exp); + std::shared_ptr b = query->getSharedBuilder(); + if (std::isnan(base) || !std::isfinite(base)) { + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(base)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3820,6 +6715,10 @@ AqlValue Functions::Pow(arangodb::aql::Query* query, AqlValue Functions::Rand(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RandVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 0) { @@ -3831,6 +6730,25 @@ AqlValue Functions::Rand(arangodb::aql::Query* query, // This Random functionality is not too good yet... double output = static_cast(std::rand()) / RAND_MAX; return AqlValue(new Json(output)); +#endif +} + +AqlValue$ Functions::RandVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 0) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "RAND", (int)0, + (int)0); + } + + // This Random functionality is not too good yet... + double output = static_cast(std::rand()) / RAND_MAX; + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(output)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3840,6 +6758,10 @@ AqlValue Functions::Rand(arangodb::aql::Query* query, AqlValue Functions::FirstDocument(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FirstDocumentVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); for (size_t i = 0; i < n; ++i) { Json element = ExtractFunctionParameter(trx, parameters, i, false); @@ -3849,6 +6771,22 @@ AqlValue Functions::FirstDocument(arangodb::aql::Query* query, } } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::FirstDocumentVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + for (size_t i = 0; i < n; ++i) { + VPackSlice element = ExtractFunctionParameter(trx, parameters, i); + if (element.isObject()) { + return AqlValue$(element); + } + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3858,6 +6796,10 @@ AqlValue Functions::FirstDocument(arangodb::aql::Query* query, AqlValue Functions::FirstList(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FirstListVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); for (size_t i = 0; i < n; ++i) { Json element = ExtractFunctionParameter(trx, parameters, i, false); @@ -3867,6 +6809,22 @@ AqlValue Functions::FirstList(arangodb::aql::Query* query, } } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::FirstListVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + for (size_t i = 0; i < n; ++i) { + VPackSlice element = ExtractFunctionParameter(trx, parameters, i); + if (element.isArray()) { + return AqlValue$(element); + } + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3876,6 +6834,10 @@ AqlValue Functions::FirstList(arangodb::aql::Query* query, AqlValue Functions::Push(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PushVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -3904,6 +6866,44 @@ AqlValue Functions::Push(arangodb::aql::Query* query, RegisterWarning(query, "PUSH", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::PushVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PUSH", (int)2, + (int)3); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice toPush = ExtractFunctionParameter(trx, parameters, 1); + + std::shared_ptr b = query->getSharedBuilder(); + if (list.isNull()) { + VPackArrayBuilder guard(b.get()); + b->add(toPush); + } else if (list.isArray()) { + VPackArrayBuilder guard(b.get()); + for (auto const& it : VPackArrayIterator(list)) { + b->add(it); + } + if (n == 3) { + VPackSlice unique = ExtractFunctionParameter(trx, parameters, 2); + if (!ValueToBoolean(unique) || !ListContainsElement(list, toPush)) { + b->add(toPush); + } + } else { + b->add(toPush); + } + } else { + RegisterWarning(query, "PUSH", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3913,6 +6913,10 @@ AqlValue Functions::Push(arangodb::aql::Query* query, AqlValue Functions::Pop(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PopVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -3937,6 +6941,43 @@ AqlValue Functions::Pop(arangodb::aql::Query* query, RegisterWarning(query, "POP", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::PopVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "POP", (int)1, + (int)1); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::shared_ptr b = query->getSharedBuilder(); + if (list.isArray()) { + try { + VPackArrayBuilder guard(b.get()); + auto iterator = VPackArrayIterator(list); + while (!iterator.isLast()) { + b->add(iterator.value()); + iterator.next(); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + } else { + RegisterWarning(query, "POP", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3946,6 +6987,10 @@ AqlValue Functions::Pop(arangodb::aql::Query* query, AqlValue Functions::Append(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AppendVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -3989,6 +7034,53 @@ AqlValue Functions::Append(arangodb::aql::Query* query, list.add(toPush.copy()); } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, list.copy().steal())); +#endif +} + +AqlValue$ Functions::AppendVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "APPEND", (int)2, + (int)3); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice toAppend = ExtractFunctionParameter(trx, parameters, 1); + + if (toAppend.isNull()) { + return AqlValue$(list); + } + + bool unique = false; + if (n == 3) { + VPackSlice uniqueSlice = ExtractFunctionParameter(trx, parameters, 2); + unique = ValueToBoolean(uniqueSlice); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + if (!list.isNull()) { + TRI_ASSERT(list.isArray()); + for (auto const& it : VPackArrayIterator(list)) { + b->add(it); + } + } + if (!toAppend.isArray()) { + if (!unique || !ListContainsElement(list, toAppend)) { + b->add(toAppend); + } + } else { + for (auto const& it : VPackArrayIterator(toAppend)) { + if (!unique || !ListContainsElement(list, it)) { + b->add(it); + } + } + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3998,6 +7090,10 @@ AqlValue Functions::Append(arangodb::aql::Query* query, AqlValue Functions::Unshift(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnshiftVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4039,6 +7135,50 @@ AqlValue Functions::Unshift(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "UNSHIFT"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::UnshiftVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNSHIFT", (int)2, + (int)3); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isNull() && !list.isArray()) { + RegisterInvalidArgumentWarning(query, "UNSHIFT"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice toAppend = ExtractFunctionParameter(trx, parameters, 1); + bool unique = false; + if (n == 3) { + VPackSlice uniqueSlice = ExtractFunctionParameter(trx, parameters, 2); + unique = ValueToBoolean(uniqueSlice); + } + + if (unique && list.isArray() && ListContainsElement(list, toAppend)) { + // Short circuit, nothing to do return list + return AqlValue$(list); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + b->add(toAppend); + if (list.isArray()) { + for (auto const& it : VPackArrayIterator(list)) { + b->add(it); + } + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4048,6 +7188,10 @@ AqlValue Functions::Unshift(arangodb::aql::Query* query, AqlValue Functions::Shift(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ShiftVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -4072,6 +7216,45 @@ AqlValue Functions::Shift(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "SHIFT"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::ShiftVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SHIFT", (int)1, + (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + if (!list.isArray()) { + RegisterInvalidArgumentWarning(query, "SHIFT"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + if (list.length() > 0) { + auto iterator = VPackArrayIterator(list); + // This jumps over the first element + while(iterator.next()) { + b->add(iterator.value()); + } + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4081,6 +7264,10 @@ AqlValue Functions::Shift(arangodb::aql::Query* query, AqlValue Functions::RemoveValue(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RemoveValueVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4124,6 +7311,67 @@ AqlValue Functions::RemoveValue(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "REMOVE_VALUE"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::RemoveValueVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "REMOVE_VALUE", + (int)2, (int)3); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (!list.isArray()) { + RegisterInvalidArgumentWarning(query, "REMOVE_VALUE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + bool useLimit = false; + size_t limit = static_cast(list.length()); + + VPackSlice toRemove = ExtractFunctionParameter(trx, parameters, 1); + if (n == 3) { + VPackSlice limitSlice = ExtractFunctionParameter(trx, parameters, 2); + bool unused = false; + if (!limitSlice.isNull()) { + limit = static_cast(ValueToNumber(limitSlice, unused)); + useLimit = true; + } + } + for (auto const& it : VPackArrayIterator(list)) { + if (useLimit && limit == 0) { + // Just copy + b->add(it); + continue; + } + if (arangodb::basics::VelocyPackHelper::compare(toRemove, it, false) == + 0) { + --limit; + continue; + } + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4133,6 +7381,10 @@ AqlValue Functions::RemoveValue(arangodb::aql::Query* query, AqlValue Functions::RemoveValues(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RemoveValuesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4166,6 +7418,50 @@ AqlValue Functions::RemoveValues(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "REMOVE_VALUES"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::RemoveValuesVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "REMOVE_VALUES", + (int)2, (int)2); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice values = ExtractFunctionParameter(trx, parameters, 1); + + if (values.isNull()) { + return AqlValue$(list); + } + + std::shared_ptr b = query->getSharedBuilder(); + if (list.isNull()) { + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (list.isArray() && values.isArray()) { + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : VPackArrayIterator(list)) { + if (!ListContainsElement(values, it)) { + b->add(it); + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); + } + + RegisterInvalidArgumentWarning(query, "REMOVE_VALUES"); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4175,6 +7471,10 @@ AqlValue Functions::RemoveValues(arangodb::aql::Query* query, AqlValue Functions::RemoveNth(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RemoveNthVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4209,6 +7509,61 @@ AqlValue Functions::RemoveNth(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "REMOVE_NTH"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::RemoveNthVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "REMOVE_NTH", (int)2, + (int)2); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (list.isArray()) { + double const count = static_cast(list.length()); + VPackSlice position = ExtractFunctionParameter(trx, parameters, 1); + bool unused = false; + double p = arangodb::basics::VelocyPackHelper::toDouble(position, unused); + if (p >= count || p < -count) { + return AqlValue$(list); + } + if (p < 0) { + p += count; + } + size_t cur = 0; + size_t target = static_cast(p); + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : VPackArrayIterator(list)) { + if (cur != target) { + b->add(it); + } + cur++; + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); + } + + RegisterInvalidArgumentWarning(query, "REMOVE_NTH"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4218,6 +7573,10 @@ AqlValue Functions::RemoveNth(arangodb::aql::Query* query, AqlValue Functions::NotNull(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NotNullVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); for (size_t i = 0; i < n; ++i) { Json element = ExtractFunctionParameter(trx, parameters, i, false); @@ -4226,8 +7585,25 @@ AqlValue Functions::NotNull(arangodb::aql::Query* query, } } return AqlValue(new Json(Json::Null)); +#endif } +AqlValue$ Functions::NotNullVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + for (size_t i = 0; i < n; ++i) { + VPackSlice element = ExtractFunctionParameter(trx, parameters, i); + if (!element.isNull()) { + return AqlValue$(element); + } + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief function CURRENT_DATABASE //////////////////////////////////////////////////////////////////////////////// @@ -4235,6 +7611,10 @@ AqlValue Functions::NotNull(arangodb::aql::Query* query, AqlValue Functions::CurrentDatabase(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(CurrentDatabaseVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 0) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4242,6 +7622,21 @@ AqlValue Functions::CurrentDatabase(arangodb::aql::Query* query, (int)0, (int)0); } return AqlValue(new Json(query->vocbase()->_name)); +#endif +} + +AqlValue$ Functions::CurrentDatabaseVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 0) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "CURRENT_DATABASE", + (int)0, (int)0); + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(query->vocbase()->_name)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4251,6 +7646,10 @@ AqlValue Functions::CurrentDatabase(arangodb::aql::Query* query, AqlValue Functions::CollectionCount(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(CollectionCountVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4300,6 +7699,62 @@ AqlValue Functions::CollectionCount(arangodb::aql::Query* query, } return AqlValue(new Json(static_cast(document->size()))); +#endif +} + +AqlValue$ Functions::CollectionCountVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "COLLECTION_COUNT", + (int)1, (int)1); + } + + VPackSlice element = ExtractFunctionParameter(trx, parameters, 0); + if (!element.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "COLLECTION_COUNT"); + } + + std::string const colName = + basics::VelocyPackHelper::getStringValue(element, ""); + + auto resolver = trx->resolver(); + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + if (cid == 0) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + + auto collection = trx->trxCollection(cid); + + // ensure the collection is loaded + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION_FORMAT(res, "'%s'", colName.c_str()); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", colName.c_str()); + } + } + + auto document = trx->documentCollection(cid); + + if (document == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(document->size())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4309,6 +7764,10 @@ AqlValue Functions::CollectionCount(arangodb::aql::Query* query, AqlValue Functions::VarianceSample(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(VarianceSampleVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4337,6 +7796,48 @@ AqlValue Functions::VarianceSample(arangodb::aql::Query* query, } return AqlValue(new Json(value / (count - 1))); +#endif +} + +AqlValue$ Functions::VarianceSampleVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "VARIANCE_SAMPLE", + (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "VARIANCE_SAMPLE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "VARIANCE_SAMPLE", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 2) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(value / (count - 1))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4346,6 +7847,10 @@ AqlValue Functions::VarianceSample(arangodb::aql::Query* query, AqlValue Functions::VariancePopulation(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(VariancePopulationVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4375,8 +7880,52 @@ AqlValue Functions::VariancePopulation(arangodb::aql::Query* query, } return AqlValue(new Json(value / count)); +#endif } +AqlValue$ Functions::VariancePopulationVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, + "VARIANCE_POPULATION", (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "VARIANCE_POPULATION", + TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "VARIANCE_POPULATION", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 1) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(value / count)); + return AqlValue$(b.get()); +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief function STDDEV_SAMPLE //////////////////////////////////////////////////////////////////////////////// @@ -4384,6 +7933,10 @@ AqlValue Functions::VariancePopulation(arangodb::aql::Query* query, AqlValue Functions::StdDevSample(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(StdDevSampleVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4412,6 +7965,48 @@ AqlValue Functions::StdDevSample(arangodb::aql::Query* query, } return AqlValue(new Json(sqrt(value / (count - 1)))); +#endif +} + +AqlValue$ Functions::StdDevSampleVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "STDDEV_SAMPLE", + (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "STDDEV_SAMPLE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "STDDEV_SAMPLE", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 2) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(sqrt(value / (count - 1) ))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4421,6 +8016,10 @@ AqlValue Functions::StdDevSample(arangodb::aql::Query* query, AqlValue Functions::StdDevPopulation(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(StdDevPopulationVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4449,6 +8048,48 @@ AqlValue Functions::StdDevPopulation(arangodb::aql::Query* query, } return AqlValue(new Json(sqrt(value / count))); +#endif +} + +AqlValue$ Functions::StdDevPopulationVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "STDDEV_POPULATION", + (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "STDDEV_POPULATION", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "STDDEV_POPULATION", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 1) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(sqrt(value / count))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4458,6 +8099,10 @@ AqlValue Functions::StdDevPopulation(arangodb::aql::Query* query, AqlValue Functions::Median(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MedianVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4488,6 +8133,51 @@ AqlValue Functions::Median(arangodb::aql::Query* query, return AqlValue(new Json((values[midpoint - 1] + values[midpoint]) / 2)); } return AqlValue(new Json(values[midpoint])); +#endif +} + +AqlValue$ Functions::MedianVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "MEDIAN", (int)1, + (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "MEDIAN", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::vector values; + if (!SortNumberList(list, values)) { + RegisterWarning(query, "MEDIAN", TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (values.empty()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + size_t const l = values.size(); + size_t midpoint = l / 2; + + std::shared_ptr b = query->getSharedBuilder(); + if (l % 2 == 0) { + b->add(VPackValue((values[midpoint - 1] + values[midpoint]) / 2)); + } else { + b->add(VPackValue(values[midpoint])); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4497,6 +8187,10 @@ AqlValue Functions::Median(arangodb::aql::Query* query, AqlValue Functions::Percentile(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PercentileVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4592,6 +8286,124 @@ AqlValue Functions::Percentile(arangodb::aql::Query* query, return AqlValue(new Json(Json::Null)); } return AqlValue(new Json(values[static_cast(pos) - 1])); +#endif +} + +AqlValue$ Functions::PercentileVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PERCENTILE", (int)2, + (int)3); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "PERCENTILE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice border = ExtractFunctionParameter(trx, parameters, 1); + + if (!border.isNumber()) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool unused = false; + double p = ValueToNumber(border, unused); + if (p <= 0 || p > 100) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool useInterpolation = false; + + if (n == 3) { + VPackSlice methodSlice = ExtractFunctionParameter(trx, parameters, 2); + if (!methodSlice.isString()) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::string method = methodSlice.copyString(); + if (method == "interpolation") { + useInterpolation = true; + } else if (method == "rank") { + useInterpolation = false; + } else { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + } + + std::vector values; + if (!SortNumberList(list, values)) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (values.empty()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + size_t l = values.size(); + if (l == 1) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(values[0])); + return AqlValue$(b.get()); + } + + TRI_ASSERT(l > 1); + + if (useInterpolation) { + double idx = p * (l + 1) / 100; + double pos = floor(idx); + + std::shared_ptr b = query->getSharedBuilder(); + if (pos >= l) { + b->add(VPackValue(values[l - 1])); + } else if (pos <= 0) { + b->add(VPackValue(VPackValueType::Null)); + } else { + double delta = idx - pos; + b->add(VPackValue(delta * (values[static_cast(pos)] - + values[static_cast(pos) - 1]) + + values[static_cast(pos) - 1])); + } + return AqlValue$(b.get()); + } + double idx = p * l / 100; + double pos = ceil(idx); + std::shared_ptr b = query->getSharedBuilder(); + if (pos >= l) { + b->add(VPackValue(values[l - 1])); + } else if (pos <= 0) { + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(values[static_cast(pos) - 1])); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4601,6 +8413,10 @@ AqlValue Functions::Percentile(arangodb::aql::Query* query, AqlValue Functions::Range(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RangeVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { @@ -4655,6 +8471,73 @@ AqlValue Functions::Range(arangodb::aql::Query* query, } } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::RangeVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "RANGE", (int)2, + (int)3); + } + + VPackSlice const leftSlice = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice const rightSlice = ExtractFunctionParameter(trx, parameters, 1); + + bool unused = true; + double from = ValueToNumber(leftSlice, unused); + double to = ValueToNumber(rightSlice, unused); + + double step = 0.0; + if (n == 3) { + VPackSlice const stepSlice = ExtractFunctionParameter(trx, parameters, 2); + if (!stepSlice.isNull()) { + step = ValueToNumber(stepSlice, unused); + } else { + // no step specified + if (from <= to) { + step = 1.0; + } else { + step = -1.0; + } + } + } else { + // no step specified + if (from <= to) { + step = 1.0; + } else { + step = -1.0; + } + } + + if (step == 0.0 || (from < to && step < 0.0) || (from > to && step > 0.0)) { + RegisterWarning(query, "RANGE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + if (step < 0.0 && to <= from) { + for (; from >= to; from += step) { + b->add(VPackValue(from)); + } + } else { + for (; from <= to; from += step) { + b->add(VPackValue(from)); + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4664,6 +8547,10 @@ AqlValue Functions::Range(arangodb::aql::Query* query, AqlValue Functions::Position(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PositionVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -4700,6 +8587,60 @@ AqlValue Functions::Position(arangodb::aql::Query* query, return AqlValue(new Json(-1)); } return AqlValue(new Json(false)); +#endif +} + +AqlValue$ Functions::PositionVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "POSITION", (int)2, + (int)3); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "POSITION", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool returnIndex = false; + if (n == 3) { + VPackSlice returnIndexSlice = ExtractFunctionParameter(trx, parameters, 2); + returnIndex = ValueToBoolean(returnIndexSlice); + } + + std::shared_ptr b = query->getSharedBuilder(); + if (list.length() > 0) { + VPackSlice searchValue = ExtractFunctionParameter(trx, parameters, 1); + + size_t index; + if (ListContainsElement(list, searchValue, index)) { + if (returnIndex) { + b->add(VPackValue(index)); + } else { + b->add(VPackValue(true)); + } + } else { + if (returnIndex) { + b->add(VPackValue(-1)); + } else { + b->add(VPackValue(false)); + } + } + } else { + if (returnIndex) { + b->add(VPackValue(-1)); + } else { + b->add(VPackValue(false)); + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -4709,6 +8650,10 @@ AqlValue Functions::Position(arangodb::aql::Query* query, AqlValue Functions::Fulltext(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FulltextVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 3 || n > 4) { @@ -4861,15 +8806,173 @@ AqlValue Functions::Fulltext(arangodb::aql::Query* query, TRI_FreeResultFulltextIndex(queryResult); THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } +#endif +} + +AqlValue$ Functions::FulltextVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 3 || n > 4) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FULLTEXT", (int)3, + (int)4); + } + + auto resolver = trx->resolver(); + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice attribute = ExtractFunctionParameter(trx, parameters, 1); + + if (!attribute.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } + + std::string attributeName = attribute.copyString(); + + VPackSlice queryString = ExtractFunctionParameter(trx, parameters, 2); + + if (!queryString.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } + + std::string queryValue = queryString.copyString(); + + size_t maxResults = 0; // 0 means "all results" + if (n >= 4) { + VPackSlice limit = ExtractFunctionParameter(trx, parameters, 3); + if (!limit.isNull() && !limit.isNumber()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } else if (limit.isNumber()) { + int64_t value = limit.getNumericValue(); + if (value > 0) { + maxResults = static_cast(value); + } + } + } + + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + auto collection = trx->trxCollection(cid); + + // ensure the collection is loaded + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION_FORMAT(res, "'%s'", colName.c_str()); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", colName.c_str()); + } + } + + auto document = trx->documentCollection(cid); + + if (document == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + + arangodb::Index* index = nullptr; + + std::vector> const search( + {{arangodb::basics::AttributeName(attributeName, false)}}); + + for (auto const& idx : document->allIndexes()) { + if (idx->type() == arangodb::Index::TRI_IDX_TYPE_FULLTEXT_INDEX) { + // test if index is on the correct field + if (arangodb::basics::AttributeName::isIdentical(idx->fields(), search, + false)) { + // match! + index = idx; + break; + } + } + } + + if (index == nullptr) { + THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FULLTEXT_INDEX_MISSING, + colName.c_str()); + } + + if (trx->orderDitch(collection) == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + TRI_fulltext_query_t* ft = + TRI_CreateQueryFulltextIndex(TRI_FULLTEXT_SEARCH_MAX_WORDS, maxResults); + + if (ft == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + bool isSubstringQuery = false; + int res = + TRI_ParseQueryFulltextIndex(ft, queryValue.c_str(), &isSubstringQuery); + + if (res != TRI_ERROR_NO_ERROR) { + TRI_FreeQueryFulltextIndex(ft); + THROW_ARANGO_EXCEPTION(res); + } + + auto fulltextIndex = static_cast(index); + // note: the following call will free "ft"! + TRI_fulltext_result_t* queryResult = + TRI_QueryFulltextIndex(fulltextIndex->internals(), ft); + + if (queryResult == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + + auto shaper = collection->_collection->_collection->getShaper(); + size_t const numResults = queryResult->_numDocuments; + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + + for (size_t i = 0; i < numResults; ++i) { + std::unordered_set unused; + ExpandShapedJson(shaper, resolver, cid, + (TRI_doc_mptr_t const*)queryResult->_documents[i], *b, + false, unused); + } + } catch (...) { + TRI_FreeResultFulltextIndex(queryResult); + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + TRI_FreeResultFulltextIndex(queryResult); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_SAME_COLLECTION //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsSameCollection (arangodb::aql::Query* query, - arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { +AqlValue Functions::IsSameCollection(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsSameCollectionVPack(query, trx, tmp)); +#else if (parameters.size() != 2) { THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "IS_SAME_COLLECTION", (int) 2, (int) 2); } @@ -4906,5 +9009,55 @@ AqlValue Functions::IsSameCollection (arangodb::aql::Query* query, RegisterWarning(query, "IS_SAME_COLLECTION", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::IsSameCollectionVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "IS_SAME_COLLECTION", + (int)2, (int)2); + } + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "IS_SAME_COLLECTION"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice value = ExtractFunctionParameter(trx, parameters, 1); + std::string identifier; + + if (value.isObject() && value.hasKey(TRI_VOC_ATTRIBUTE_ID)) { + identifier = arangodb::basics::VelocyPackHelper::getStringValue( + value, TRI_VOC_ATTRIBUTE_ID, ""); + } else if (value.isString()) { + identifier = value.copyString(); + } + + if (!identifier.empty()) { + size_t pos = identifier.find('/'); + + if (pos != std::string::npos) { + bool const same = (colName == identifier.substr(0, pos)); + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(same)); + return AqlValue$(b.get()); + } + + // fallthrough intentional + } + + RegisterWarning(query, "IS_SAME_COLLECTION", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 980f4f1a62..83cd20bb72 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -30,6 +30,8 @@ #include +#define TMPUSEVPACK 1 + namespace arangodb { namespace aql { @@ -40,6 +42,8 @@ typedef std::function ExecutionCondition; typedef std::vector> FunctionParameters; +typedef std::vector VPackFunctionParameters; + typedef std::function FunctionImplementation; @@ -61,12 +65,8 @@ struct Functions { static AqlValue IsNull(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - FunctionParameters const&); static AqlValue IsBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - FunctionParameters const&); static AqlValue IsNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue IsString(arangodb::aql::Query*, arangodb::AqlTransaction*, @@ -223,6 +223,194 @@ struct Functions { FunctionParameters const&); static AqlValue IsSameCollection(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + + + static AqlValue$ IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ IsNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ IsStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ IsArrayVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ IsObjectVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ToNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ToStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ToArrayVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ LengthVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ FirstVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ LastVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ NthVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ConcatVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ LikeVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ PassthruVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ UnsetVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ UnsetRecursiveVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ KeepVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ MergeVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ MergeRecursiveVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ HasVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ AttributesVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ValuesVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ MinVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ MaxVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ SumVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ AverageVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ Md5VPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ Sha1VPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ UniqueVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ SortedUniqueVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ UnionVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ UnionDistinctVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ IntersectionVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ NeighborsVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ NearVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ WithinVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ FlattenVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ZipVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ParseIdentifierVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ MinusVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ DocumentVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ EdgesVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ RoundVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ AbsVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ CeilVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ FloorVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ SqrtVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ PowVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ RandVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ FirstDocumentVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ FirstListVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ PushVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ PopVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ AppendVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ UnshiftVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ ShiftVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ RemoveValueVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ RemoveValuesVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ RemoveNthVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ NotNullVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ CurrentDatabaseVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ CollectionCountVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ VarianceSampleVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ VariancePopulationVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ StdDevSampleVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ StdDevPopulationVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ MedianVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ PercentileVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ RangeVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ PositionVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ FulltextVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); + static AqlValue$ IsSameCollectionVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); }; } } diff --git a/arangod/Aql/Graphs.cpp b/arangod/Aql/Graphs.cpp index ad0c4995ec..679301b5da 100644 --- a/arangod/Aql/Graphs.cpp +++ b/arangod/Aql/Graphs.cpp @@ -24,6 +24,8 @@ #include "Graphs.h" #include "Basics/JsonHelper.h" +#include + using namespace arangodb::basics; using namespace arangodb::aql; @@ -79,6 +81,26 @@ arangodb::basics::Json Graph::toJson(TRI_memory_zone_t* z, bool verbose) const { return json; } +void Graph::toVelocyPack(VPackBuilder& builder, bool verbose) const { + VPackObjectBuilder guard(&builder); + + if (!_vertexColls.empty()) { + builder.add(VPackValue("vertexCollectionNames")); + VPackArrayBuilder guard2(&builder); + for (auto const& cn : _vertexColls) { + builder.add(VPackValue(cn)); + } + } + + if (!_edgeColls.empty()) { + builder.add(VPackValue("edgeCollectionNames")); + VPackArrayBuilder guard2(&builder); + for (auto const& cn : _edgeColls) { + builder.add(VPackValue(cn)); + } + } +} + Graph::Graph(arangodb::basics::Json const& j) : _vertexColls(), _edgeColls() { auto jsonDef = j.get(_attrEdgeDefs); diff --git a/arangod/Aql/Graphs.h b/arangod/Aql/Graphs.h index 1cc8b154bb..69efac9373 100644 --- a/arangod/Aql/Graphs.h +++ b/arangod/Aql/Graphs.h @@ -105,6 +105,12 @@ class Graph { ////////////////////////////////////////////////////////////////////////////// arangodb::basics::Json toJson(TRI_memory_zone_t*, bool) const; + + ////////////////////////////////////////////////////////////////////////////// + /// @brief return a VelocyPack representation of the graph + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(arangodb::velocypack::Builder&, bool) const; }; } // namespace aql diff --git a/arangod/Aql/Index.cpp b/arangod/Aql/Index.cpp index ff58ae771a..f7c1160612 100644 --- a/arangod/Aql/Index.cpp +++ b/arangod/Aql/Index.cpp @@ -40,6 +40,33 @@ Index::~Index() { } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Create a VelocyPack representation of the index +//////////////////////////////////////////////////////////////////////////////// + +void Index::toVelocyPack(VPackBuilder& builder) const { + VPackObjectBuilder guard(&builder); + + builder.add("type", VPackValue(arangodb::Index::typeName(type))); + builder.add("id", VPackValue(arangodb::basics::StringUtils::itoa(id))); + builder.add("unique", VPackValue(unique)); + builder.add("sparse", VPackValue(sparse)); + + if (hasSelectivityEstimate()) { + builder.add("selectivityEstimate", VPackValue(selectivityEstimate())); + } + + builder.add(VPackValue("fields")); + { + VPackArrayBuilder arrayGuard(&builder); + for (auto const& field : fields) { + std::string tmp; + TRI_AttributeNamesToString(field, tmp); + builder.add(VPackValue(tmp)); + } + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief get the index internals //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Index.h b/arangod/Aql/Index.h index f568d5a94b..3b4aae71e5 100644 --- a/arangod/Aql/Index.h +++ b/arangod/Aql/Index.h @@ -125,6 +125,12 @@ struct Index { return json; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Create a VelocyPack representation of the index +//////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(VPackBuilder&) const; + bool hasSelectivityEstimate() const { if (!hasInternals()) { return false; diff --git a/arangod/Aql/IndexNode.cpp b/arangod/Aql/IndexNode.cpp index 3c196f3cf0..ebf7f8578f 100644 --- a/arangod/Aql/IndexNode.cpp +++ b/arangod/Aql/IndexNode.cpp @@ -33,36 +33,32 @@ using namespace arangodb::aql; using JsonHelper = arangodb::basics::JsonHelper; //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for IndexNode +/// @brief toVelocyPack, for IndexNode //////////////////////////////////////////////////////////////////////////////// -void IndexNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json( - ExecutionNode::toJsonHelperGeneric(nodes, zone, verbose)); - // call base class method - - if (json.isEmpty()) { - return; - } +void IndexNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method // Now put info about vocbase and cid in there - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName()))( - "outVariable", _outVariable->toJson()); + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); - arangodb::basics::Json indexes(arangodb::basics::Json::Array, - _indexes.size()); - for (auto& index : _indexes) { - indexes.add(index->toJson()); + nodes.add(VPackValue("indexes")); + { + VPackArrayBuilder guard(&nodes); + for (auto& index : _indexes) { + index->toVelocyPack(nodes); + } } + nodes.add(VPackValue("condition")); + _condition->toVelocyPack(nodes, verbose); + nodes.add("reverse", VPackValue(_reverse)); - json("indexes", indexes); - json("condition", _condition->toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); - json("reverse", arangodb::basics::Json(_reverse)); - - // And add it: - nodes(json); + // And close it: + nodes.close(); } ExecutionNode* IndexNode::clone(ExecutionPlan* plan, bool withDependencies, diff --git a/arangod/Aql/IndexNode.h b/arangod/Aql/IndexNode.h index e5497d40b6..7096e36df3 100644 --- a/arangod/Aql/IndexNode.h +++ b/arangod/Aql/IndexNode.h @@ -108,11 +108,11 @@ class IndexNode : public ExecutionNode { bool reverse() const { return _reverse; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively diff --git a/arangod/Aql/ModificationNodes.cpp b/arangod/Aql/ModificationNodes.cpp index 39f6e96289..abb2bf551a 100644 --- a/arangod/Aql/ModificationNodes.cpp +++ b/arangod/Aql/ModificationNodes.cpp @@ -47,24 +47,28 @@ ModificationNode::ModificationNode(ExecutionPlan* plan, } //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson +/// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// -void ModificationNode::toJsonHelper(arangodb::basics::Json& json, - TRI_memory_zone_t* zone, bool) const { +void ModificationNode::toVelocyPackHelper(VPackBuilder& builder, + bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(builder, + verbose); // call base class method // Now put info about vocbase and cid in there - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName())); + builder.add("database", VPackValue(_vocbase->_name)); + builder.add("collection", VPackValue(_collection->getName())); // add out variables if (_outVariableOld != nullptr) { - json("outVariableOld", _outVariableOld->toJson()); + builder.add(VPackValue("outVariableOld")); + _outVariableOld->toVelocyPack(builder); } if (_outVariableNew != nullptr) { - json("outVariableNew", _outVariableNew->toJson()); + builder.add(VPackValue("outVariableNew")); + _outVariableNew->toVelocyPack(builder); } - - _options.toJson(json, zone); + builder.add(VPackValue("modificationFlags")); + _options.toVelocyPack(builder); } //////////////////////////////////////////////////////////////////////////////// @@ -94,22 +98,13 @@ RemoveNode::RemoveNode(ExecutionPlan* plan, arangodb::basics::Json const& base) /// @brief toJson //////////////////////////////////////////////////////////////////////////////// -void RemoveNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method +void RemoveNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ModificationNode::toVelocyPackHelper(nodes, verbose); + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); - if (json.isEmpty()) { - return; - } - - // Now put info about vocbase and cid in there - json("inVariable", _inVariable->toJson()); - - ModificationNode::toJsonHelper(json, zone, verbose); - - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// @@ -142,25 +137,19 @@ InsertNode::InsertNode(ExecutionPlan* plan, arangodb::basics::Json const& base) _inVariable(varFromJson(plan->getAst(), base, "inVariable")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson +/// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// -void InsertNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } +void InsertNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ModificationNode::toVelocyPackHelper(nodes, + verbose); // call base class method // Now put info about vocbase and cid in there - json("inVariable", _inVariable->toJson()); + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); - ModificationNode::toJsonHelper(json, zone, verbose); - - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// @@ -195,30 +184,23 @@ UpdateNode::UpdateNode(ExecutionPlan* plan, arangodb::basics::Json const& base) varFromJson(plan->getAst(), base, "inKeyVariable", Optional)) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson +/// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// -void UpdateNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } - - // Now put info about vocbase and cid in there - json("inDocVariable", _inDocVariable->toJson()); - - ModificationNode::toJsonHelper(json, zone, verbose); +void UpdateNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ModificationNode::toVelocyPackHelper(nodes, verbose); + + nodes.add(VPackValue("inDocVariable")); + _inDocVariable->toVelocyPack(nodes); // inKeyVariable might be empty if (_inKeyVariable != nullptr) { - json("inKeyVariable", _inKeyVariable->toJson()); + nodes.add(VPackValue("inKeyVariable")); + _inKeyVariable->toVelocyPack(nodes); } - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// @@ -265,30 +247,23 @@ ReplaceNode::ReplaceNode(ExecutionPlan* plan, varFromJson(plan->getAst(), base, "inKeyVariable", Optional)) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson +/// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// -void ReplaceNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } - - // Now put info about vocbase and cid in there - json("inDocVariable", _inDocVariable->toJson()); - - ModificationNode::toJsonHelper(json, zone, verbose); +void ReplaceNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ModificationNode::toVelocyPackHelper(nodes, verbose); + + nodes.add(VPackValue("inDocVariable")); + _inDocVariable->toVelocyPack(nodes); // inKeyVariable might be empty if (_inKeyVariable != nullptr) { - json("inKeyVariable", _inKeyVariable->toJson()); + nodes.add(VPackValue("inKeyVariable")); + _inKeyVariable->toVelocyPack(nodes); } - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// @@ -336,27 +311,23 @@ UpsertNode::UpsertNode(ExecutionPlan* plan, arangodb::basics::Json const& base) JsonHelper::checkAndGetBooleanValue(base.json(), "isReplace")) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson +/// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// -void UpsertNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method +void UpsertNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ModificationNode::toVelocyPackHelper(nodes, verbose); - if (json.isEmpty()) { - return; - } + nodes.add(VPackValue("inDocVariable")); + _inDocVariable->toVelocyPack(nodes); + nodes.add(VPackValue("insertVariable")); + _insertVariable->toVelocyPack(nodes); + nodes.add(VPackValue("updateVariable")); + _updateVariable->toVelocyPack(nodes); + nodes.add("isReplace", VPackValue(_isReplace)); - ModificationNode::toJsonHelper(json, zone, verbose); - - json("inDocVariable", _inDocVariable->toJson()); - json("insertVariable", _insertVariable->toJson()); - json("updateVariable", _updateVariable->toJson()); - json("isReplace", arangodb::basics::Json(_isReplace)); - - // And add it: - nodes(json); + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ModificationNodes.h b/arangod/Aql/ModificationNodes.h index 595ce943d7..fa20e62baa 100644 --- a/arangod/Aql/ModificationNodes.h +++ b/arangod/Aql/ModificationNodes.h @@ -70,11 +70,11 @@ class ModificationNode : public ExecutionNode { ModificationNode(ExecutionPlan*, arangodb::basics::Json const& json); ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - virtual void toJsonHelper(arangodb::basics::Json& json, - TRI_memory_zone_t* zone, bool) const override; + virtual void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override; public: ////////////////////////////////////////////////////////////////////////////// @@ -214,11 +214,11 @@ class RemoveNode : public ModificationNode { NodeType getType() const override final { return REMOVE; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -281,11 +281,11 @@ class InsertNode : public ModificationNode { NodeType getType() const override final { return INSERT; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -354,11 +354,11 @@ class UpdateNode : public ModificationNode { NodeType getType() const override final { return UPDATE; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -444,11 +444,11 @@ class ReplaceNode : public ModificationNode { NodeType getType() const override final { return REPLACE; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively @@ -540,11 +540,11 @@ class UpsertNode : public ModificationNode { NodeType getType() const override final { return UPSERT; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively diff --git a/arangod/Aql/ModificationOptions.cpp b/arangod/Aql/ModificationOptions.cpp index f524f1c5dc..81bf4c44bc 100644 --- a/arangod/Aql/ModificationOptions.cpp +++ b/arangod/Aql/ModificationOptions.cpp @@ -23,6 +23,8 @@ #include "Aql/ModificationOptions.h" +#include + using namespace arangodb::aql; using Json = arangodb::basics::Json; using JsonHelper = arangodb::basics::JsonHelper; @@ -54,3 +56,13 @@ void ModificationOptions::toJson(arangodb::basics::Json& json, json("modificationFlags", flags); } + +void ModificationOptions::toVelocyPack(VPackBuilder& builder) const { + VPackObjectBuilder guard(&builder); + builder.add("ignoreErrors", VPackValue(ignoreErrors)); + builder.add("waitForSync", VPackValue(waitForSync)); + builder.add("nullMeansRemove", VPackValue(nullMeansRemove)); + builder.add("mergeObjects", VPackValue(mergeObjects)); + builder.add("ignoreDocumentNotFound", VPackValue(ignoreDocumentNotFound)); + builder.add("readCompleteInput", VPackValue(readCompleteInput)); +} diff --git a/arangod/Aql/ModificationOptions.h b/arangod/Aql/ModificationOptions.h index d6f8939f21..b119124b89 100644 --- a/arangod/Aql/ModificationOptions.h +++ b/arangod/Aql/ModificationOptions.h @@ -51,6 +51,8 @@ struct ModificationOptions { void toJson(arangodb::basics::Json&, TRI_memory_zone_t*) const; + void toVelocyPack(arangodb::velocypack::Builder&) const; + bool ignoreErrors; bool waitForSync; bool nullMeansRemove; diff --git a/arangod/Aql/Query.cpp b/arangod/Aql/Query.cpp index 820cfe26cd..5d67350e89 100644 --- a/arangod/Aql/Query.cpp +++ b/arangod/Aql/Query.cpp @@ -1470,6 +1470,15 @@ std::string Query::getStateString() const { return std::string(" (while " + StateNames[_state] + ")"); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief get a shared builder for in-place VelocyPack construction +//////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr Query::getSharedBuilder () { + // TODO Proper memory efficient implementation + return std::make_shared(); +}; + //////////////////////////////////////////////////////////////////////////////// /// @brief cleanup plan and engine for current query //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Query.h b/arangod/Aql/Query.h index 3388b29e20..ba0dadeaef 100644 --- a/arangod/Aql/Query.h +++ b/arangod/Aql/Query.h @@ -417,6 +417,12 @@ class Query { std::string getStateString () const; + //////////////////////////////////////////////////////////////////////////////// + /// @brief get a shared builder for in-place VelocyPack construction + //////////////////////////////////////////////////////////////////////////////// + + std::shared_ptr getSharedBuilder (); + // ----------------------------------------------------------------------------- // --SECTION-- private methods // ----------------------------------------------------------------------------- diff --git a/arangod/Aql/SortNode.cpp b/arangod/Aql/SortNode.cpp index 6de2b6ec85..2d5a25ef50 100644 --- a/arangod/Aql/SortNode.cpp +++ b/arangod/Aql/SortNode.cpp @@ -35,30 +35,27 @@ SortNode::SortNode(ExecutionPlan* plan, arangodb::basics::Json const& base, : ExecutionNode(plan, base), _elements(elements), _stable(stable) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for SortNode +/// @brief toVelocyPack, for SortNode //////////////////////////////////////////////////////////////////////////////// -void SortNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method +void SortNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method - if (json.isEmpty()) { - return; + nodes.add(VPackValue("elements")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& it : _elements) { + VPackObjectBuilder obj(&nodes); + nodes.add(VPackValue("inVariable")); + it.first->toVelocyPack(nodes); + nodes.add("ascending", VPackValue(it.second)); + } } - arangodb::basics::Json values(arangodb::basics::Json::Array, - _elements.size()); - for (auto it = _elements.begin(); it != _elements.end(); ++it) { - arangodb::basics::Json element(arangodb::basics::Json::Object); - element("inVariable", (*it).first->toJson())( - "ascending", arangodb::basics::Json((*it).second)); - values(element); - } - json("elements", values); - json("stable", arangodb::basics::Json(_stable)); + nodes.add("stable", VPackValue(_stable)); - // And add it: - nodes(json); + // And close it: + nodes.close(); } class SortNodeFindMyExpressions : public WalkerWorker { diff --git a/arangod/Aql/SortNode.h b/arangod/Aql/SortNode.h index 8976f5cb2e..e5fb8b7531 100644 --- a/arangod/Aql/SortNode.h +++ b/arangod/Aql/SortNode.h @@ -73,11 +73,11 @@ class SortNode : public ExecutionNode { inline bool isStable() const { return _stable; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively diff --git a/arangod/Aql/TraversalNode.cpp b/arangod/Aql/TraversalNode.cpp index f03e68efe2..2db9c8ad47 100644 --- a/arangod/Aql/TraversalNode.cpp +++ b/arangod/Aql/TraversalNode.cpp @@ -87,6 +87,25 @@ void SimpleTraverserExpression::toJson(arangodb::basics::Json& json, "compareTo", compareToNode->toJson(zone, true)); } +void SimpleTraverserExpression::toVelocyPack(VPackBuilder& builder) const { + TRI_ASSERT(builder.isOpenObject()); + auto op = arangodb::aql::AstNode::Operators.find(comparisonType); + + if (op == arangodb::aql::AstNode::Operators.end()) { + THROW_ARANGO_EXCEPTION_MESSAGE( + TRI_ERROR_QUERY_PARSE, + "invalid operator for simpleTraverserExpression"); + } + std::string const operatorStr = op->second; + builder.add("isEdgeAccess", VPackValue(isEdgeAccess)); + builder.add("comparisonTypeStr", VPackValue(operatorStr)); + builder.add("comparisonType", VPackValue(comparisonType)); + builder.add(VPackValue("varAccess")); + varAccess->toVelocyPack(builder, true); + builder.add(VPackValue("compareTo")); + compareToNode->toVelocyPack(builder, true); +} + static TRI_edge_direction_e parseDirection (AstNode const* node) { TRI_ASSERT(node->isIntValue()); auto dirNum = node->getIntValue(); @@ -445,75 +464,81 @@ int TraversalNode::checkIsOutVariable(size_t variableId) const { } //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for TraversalNode +/// @brief toVelocyPack, for TraversalNode //////////////////////////////////////////////////////////////////////////////// -void TraversalNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, bool verbose) const { - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method +void TraversalNode::toVelocyPackHelper(arangodb::velocypack::Builder& nodes, + bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method - if (json.isEmpty()) { - return; + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("minDepth", VPackValue(_minDepth)); + nodes.add("maxDepth", VPackValue(_maxDepth)); + + { + // TODO Remove _graphJson + auto tmp = arangodb::basics::JsonHelper::toVelocyPack(_graphJson.json()); + nodes.add("graph", tmp->slice()); } - - json("database", arangodb::basics::Json(_vocbase->_name))( - "minDepth", arangodb::basics::Json(static_cast(_minDepth)))( - "maxDepth", arangodb::basics::Json(static_cast(_maxDepth)))( - "graph", _graphJson.copy()); - - arangodb::basics::Json dirJson = arangodb::basics::Json(arangodb::basics::Json::Array, _directions.size()); - for (auto const& d : _directions) { - dirJson.add(arangodb::basics::Json(static_cast(d))); + nodes.add(VPackValue("directions")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& d : _directions) { + nodes.add(VPackValue(d)); + } } - json("directions", dirJson); // In variable if (usesInVariable()) { - json("inVariable", inVariable()->toJson()); + nodes.add(VPackValue("inVariable")); + inVariable()->toVelocyPack(nodes); } else { - json("vertexId", arangodb::basics::Json(_vertexId)); + nodes.add("vertexId", VPackValue(_vertexId)); } if (_condition != nullptr) { - json("condition", _condition->toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); + nodes.add(VPackValue("condition")); + _condition->toVelocyPack(nodes, verbose); } if (_graphObj != nullptr) { - json("graphDefinition", _graphObj->toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); + nodes.add(VPackValue("graphDefinition")); + _graphObj->toVelocyPack(nodes, verbose); } // Out variables if (usesVertexOutVariable()) { - json("vertexOutVariable", vertexOutVariable()->toJson()); + nodes.add(VPackValue("vertexOutVariable")); + vertexOutVariable()->toVelocyPack(nodes); } if (usesEdgeOutVariable()) { - json("edgeOutVariable", edgeOutVariable()->toJson()); + nodes.add(VPackValue("edgeOutVariable")); + edgeOutVariable()->toVelocyPack(nodes); } if (usesPathOutVariable()) { - json("pathOutVariable", pathOutVariable()->toJson()); + nodes.add(VPackValue("pathOutVariable")); + pathOutVariable()->toVelocyPack(nodes); } if (!_expressions.empty()) { - arangodb::basics::Json expressionObject = arangodb::basics::Json( - arangodb::basics::Json::Object, _expressions.size()); + nodes.add(VPackValue("simpleExpressions")); + VPackObjectBuilder guard(&nodes); for (auto const& map : _expressions) { - arangodb::basics::Json expressionArray = arangodb::basics::Json( - arangodb::basics::Json::Array, map.second.size()); + nodes.add(VPackValue(std::to_string(map.first))); + VPackArrayBuilder guard2(&nodes); for (auto const& x : map.second) { - arangodb::basics::Json exp(zone, arangodb::basics::Json::Object); + VPackObjectBuilder guard3(&nodes); auto tmp = dynamic_cast(x); if (tmp != nullptr) { - tmp->toJson(exp, zone); + tmp->toVelocyPack(nodes); } - expressionArray(exp); } - expressionObject.set(std::to_string(map.first), expressionArray); } - json("simpleExpressions", expressionObject); } - // And add it: - nodes(json); + + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/TraversalNode.h b/arangod/Aql/TraversalNode.h index 497f916c95..42c3bcbda4 100644 --- a/arangod/Aql/TraversalNode.h +++ b/arangod/Aql/TraversalNode.h @@ -53,6 +53,8 @@ class SimpleTraverserExpression ~SimpleTraverserExpression(); void toJson(arangodb::basics::Json& json, TRI_memory_zone_t* zone) const; + + void toVelocyPack(arangodb::velocypack::Builder&) const; }; //////////////////////////////////////////////////////////////////////////////// @@ -103,11 +105,11 @@ class TraversalNode : public ExecutionNode { NodeType getType() const override final { return TRAVERSAL; } ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON + /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively diff --git a/arangod/Aql/Variable.cpp b/arangod/Aql/Variable.cpp index 03cdc2a108..7bfa9aef39 100644 --- a/arangod/Aql/Variable.cpp +++ b/arangod/Aql/Variable.cpp @@ -24,6 +24,8 @@ #include "Variable.h" #include "Basics/JsonHelper.h" +#include + using namespace arangodb::aql; using JsonHelper = arangodb::basics::JsonHelper; @@ -75,6 +77,16 @@ arangodb::basics::Json Variable::toJson() const { return json; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief return a VelocyPack representation of the variable +//////////////////////////////////////////////////////////////////////////////// + +void Variable::toVelocyPack(VPackBuilder& builder) const { + VPackObjectBuilder b(&builder); + builder.add("id", VPackValue(static_cast(id))); + builder.add("name", VPackValue(name)); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief replace a variable by another //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Variable.h b/arangod/Aql/Variable.h index bd06035060..2b612570c4 100644 --- a/arangod/Aql/Variable.h +++ b/arangod/Aql/Variable.h @@ -86,6 +86,12 @@ struct Variable { arangodb::basics::Json toJson() const; + ////////////////////////////////////////////////////////////////////////////// + /// @brief return a VelocyPack representation of the variable + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(arangodb::velocypack::Builder&) const; + ////////////////////////////////////////////////////////////////////////////// /// @brief replace a variable by another ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Cluster/ClusterMethods.cpp b/arangod/Cluster/ClusterMethods.cpp index 1237cb7e65..90918a0311 100644 --- a/arangod/Cluster/ClusterMethods.cpp +++ b/arangod/Cluster/ClusterMethods.cpp @@ -175,6 +175,22 @@ bool shardKeysChanged(std::string const& dbname, std::string const& collname, return false; } +bool shardKeysChanged(std::string const& dbname, std::string const& collname, + VPackSlice const& oldSlice, VPackSlice const& newSlice, + bool isPatch) { + std::unique_ptr tmpOld( + arangodb::basics::VelocyPackHelper::velocyPackToJson(oldSlice)); + if (tmpOld == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + std::unique_ptr tmpNew( + arangodb::basics::VelocyPackHelper::velocyPackToJson(newSlice)); + if (tmpNew == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return shardKeysChanged(dbname, collname, tmpOld.get(), tmpNew.get(), isPatch); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief returns users //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Cluster/ClusterMethods.h b/arangod/Cluster/ClusterMethods.h index 6d5fe936f7..b16df08ce6 100644 --- a/arangod/Cluster/ClusterMethods.h +++ b/arangod/Cluster/ClusterMethods.h @@ -68,6 +68,10 @@ bool shardKeysChanged(std::string const& dbname, std::string const& collname, struct TRI_json_t const* oldJson, struct TRI_json_t const* newJson, bool isPatch); +bool shardKeysChanged(std::string const& dbname, std::string const& collname, + VPackSlice const& oldSlice, VPackSlice const& newSlice, + bool isPatch); + //////////////////////////////////////////////////////////////////////////////// /// @brief returns users //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Scheduler/PeriodicTask.cpp b/arangod/Scheduler/PeriodicTask.cpp index eb45c31b94..b31e23b047 100644 --- a/arangod/Scheduler/PeriodicTask.cpp +++ b/arangod/Scheduler/PeriodicTask.cpp @@ -23,7 +23,6 @@ //////////////////////////////////////////////////////////////////////////////// #include "PeriodicTask.h" -#include "Basics/json.h" #include "Scheduler/Scheduler.h" #include diff --git a/arangod/V8Server/V8Traverser.cpp b/arangod/V8Server/V8Traverser.cpp index d39358373f..52f700ed8b 100644 --- a/arangod/V8Server/V8Traverser.cpp +++ b/arangod/V8Server/V8Traverser.cpp @@ -296,6 +296,23 @@ void BasicOptions::addEdgeFilter(Json const& example, VocShaper* shaper, } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Insert a new edge matcher object +//////////////////////////////////////////////////////////////////////////////// + +void BasicOptions::addEdgeFilter(VPackSlice const& example, VocShaper* shaper, + TRI_voc_cid_t const& cid, + CollectionNameResolver const* resolver) { + useEdgeFilter = true; + auto it = _edgeFilter.find(cid); + if (it == _edgeFilter.end()) { + _edgeFilter.emplace(cid, + new ExampleMatcher(example, shaper, resolver, true)); + } +} + + + //////////////////////////////////////////////////////////////////////////////// /// @brief Checks if an edge matches to given examples //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/V8Server/V8Traverser.h b/arangod/V8Server/V8Traverser.h index f26beda37c..0873ef8a8b 100644 --- a/arangod/V8Server/V8Traverser.h +++ b/arangod/V8Server/V8Traverser.h @@ -30,6 +30,10 @@ #include "VocBase/Traverser.h" namespace arangodb { +namespace velocypack { +class Slice; +} + class Transaction; } @@ -117,6 +121,10 @@ struct BasicOptions { TRI_voc_cid_t const& cid, arangodb::CollectionNameResolver const* resolver); + void addEdgeFilter(arangodb::velocypack::Slice const& example, VocShaper* shaper, + TRI_voc_cid_t const& cid, + arangodb::CollectionNameResolver const* resolver); + void addVertexFilter(v8::Isolate* isolate, v8::Handle const& example, arangodb::ExplicitTransaction* trx, diff --git a/arangod/V8Server/v8-collection.cpp b/arangod/V8Server/v8-collection.cpp index b8e7620771..6d34f52281 100644 --- a/arangod/V8Server/v8-collection.cpp +++ b/arangod/V8Server/v8-collection.cpp @@ -689,8 +689,9 @@ static void ModifyVocbaseColCoordinator( TRI_V8_THROW_EXCEPTION(error); } - std::unique_ptr json(TRI_ObjectToJson(isolate, args[1])); - if (!TRI_IsObjectJson(json.get())) { + VPackBuilder builder; + int res = TRI_V8ToVPack(isolate, builder, args[1], false); + if (res != TRI_ERROR_NO_ERROR || !builder.slice().isObject()) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID); } @@ -702,7 +703,8 @@ static void ModifyVocbaseColCoordinator( error = arangodb::modifyDocumentOnCoordinator( dbname, collname, key, rev, policy, waitForSync, isPatch, keepNull, - mergeObjects, json, headers, responseCode, resultHeaders, resultBody); + mergeObjects, builder.slice(), headers, responseCode, resultHeaders, + resultBody); if (error != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION(error); @@ -710,29 +712,24 @@ static void ModifyVocbaseColCoordinator( // report what the DBserver told us: this could now be 201/202 or // 400/404 - json.reset(TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, resultBody.c_str())); + std::shared_ptr resBuilder = VPackParser::fromJson(resultBody); + VPackSlice resSlice = resBuilder->slice(); if (responseCode >= arangodb::rest::HttpResponse::BAD) { - if (!TRI_IsObjectJson(json.get())) { + if (!resSlice.isObject()) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL); } - int errorNum = 0; - TRI_json_t* subjson = TRI_LookupObjectJson(json.get(), "errorNum"); - if (TRI_IsNumberJson(subjson)) { - errorNum = static_cast(subjson->_value._number); - } - std::string errorMessage; - subjson = TRI_LookupObjectJson(json.get(), "errorMessage"); - if (TRI_IsStringJson(subjson)) { - errorMessage = std::string(subjson->_value._string.data, - subjson->_value._string.length - 1); - } + int errorNum = arangodb::basics::VelocyPackHelper::getNumericValue( + resSlice, "errorNum", 0); + std::string errorMessage = + arangodb::basics::VelocyPackHelper::getStringValue(resSlice, + "errorMessage", ""); TRI_V8_THROW_EXCEPTION_MESSAGE(errorNum, errorMessage); } if (silent) { TRI_V8_RETURN_TRUE(); } else { - v8::Handle ret = TRI_ObjectJson(isolate, json.get()); + v8::Handle ret = TRI_VPackToV8(isolate, resSlice); TRI_V8_RETURN(ret); } } @@ -872,40 +869,40 @@ static void ReplaceVocbaseCol(bool useCollection, // compare attributes in shardKeys std::string const cidString = StringUtils::itoa(document->_info.planId()); - TRI_json_t* json = TRI_ObjectToJson(isolate, args[1]); + VPackBuilder builder; + res = TRI_V8ToVPack(isolate, builder, args[1], false); - if (json == nullptr) { - TRI_V8_THROW_EXCEPTION_MEMORY(); + if (res != TRI_ERROR_NO_ERROR) { + TRI_V8_THROW_EXCEPTION(res); } res = trx.read(&mptr, key.get()); if (res != TRI_ERROR_NO_ERROR || mptr.getDataPtr() == nullptr) { // PROTECTED by trx here - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); TRI_V8_THROW_EXCEPTION(res); } TRI_shaped_json_t shaped; TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, mptr.getDataPtr()); // PROTECTED by trx here - TRI_json_t* old = TRI_JsonShapedJson(document->getShaper(), - &shaped); // PROTECTED by trx here + std::shared_ptr oldBuilder = TRI_VelocyPackShapedJson( + document->getShaper(), &shaped); // PROTECTED by trx here - if (old == nullptr) { - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); + if (oldBuilder == nullptr) { TRI_V8_THROW_EXCEPTION_MEMORY(); } - if (shardKeysChanged(col->_dbName, cidString, old, json, false)) { - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, old); - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); + VPackSlice const old = oldBuilder->slice(); + + if (old.isNone()) { + TRI_V8_THROW_EXCEPTION_MEMORY(); + } + + if (shardKeysChanged(col->_dbName, cidString, old, builder.slice(), false)) { TRI_V8_THROW_EXCEPTION( TRI_ERROR_CLUSTER_MUST_NOT_CHANGE_SHARDING_ATTRIBUTES); } - - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, old); } TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object( @@ -1339,9 +1336,17 @@ static void UpdateVocbaseCol(bool useCollection, TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID); } - TRI_json_t* json = TRI_ObjectToJson(isolate, args[1]); + VPackBuilder builder; + { + int res = TRI_V8ToVPack(isolate, builder, args[1], false); - if (json == nullptr) { + if (res != TRI_ERROR_NO_ERROR) { + TRI_V8_THROW_EXCEPTION(res); + } + } + VPackSlice slice = builder.slice(); + + if (slice.isNone()) { TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_errno(), " is no valid JSON"); } @@ -1350,7 +1355,6 @@ static void UpdateVocbaseCol(bool useCollection, int res = trx.begin(); if (res != TRI_ERROR_NO_ERROR) { - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); TRI_V8_THROW_EXCEPTION(res); } @@ -1362,27 +1366,27 @@ static void UpdateVocbaseCol(bool useCollection, res = trx.read(&mptr, key.get()); if (res != TRI_ERROR_NO_ERROR) { - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); TRI_V8_THROW_EXCEPTION(res); } if (trx.orderDitch(trx.trxCollection()) == nullptr) { - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); TRI_V8_THROW_EXCEPTION_MEMORY(); } TRI_document_collection_t* document = trx.documentCollection(); - TRI_memory_zone_t* zone = - document->getShaper()->memoryZone(); // PROTECTED by trx here TRI_shaped_json_t shaped; TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, mptr.getDataPtr()); // PROTECTED by trx here - TRI_json_t* old = TRI_JsonShapedJson(document->getShaper(), - &shaped); // PROTECTED by trx here + std::shared_ptr oldBuilder = + TRI_VelocyPackShapedJson(document->getShaper(), + &shaped); // PROTECTED by trx here + if (oldBuilder == nullptr) { + TRI_V8_THROW_EXCEPTION_MEMORY(); + } - if (old == nullptr) { - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); + VPackSlice old = oldBuilder->slice(); + if (old.isNone()) { TRI_V8_THROW_EXCEPTION_MEMORY(); } @@ -1390,32 +1394,25 @@ static void UpdateVocbaseCol(bool useCollection, // compare attributes in shardKeys std::string const cidString = StringUtils::itoa(document->_info.planId()); - if (shardKeysChanged(col->_dbName, cidString, old, json, true)) { - TRI_FreeJson(document->getShaper()->memoryZone(), - old); // PROTECTED by trx here - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); - + if (shardKeysChanged(col->_dbName, cidString, old, slice, true)) { TRI_V8_THROW_EXCEPTION( TRI_ERROR_CLUSTER_MUST_NOT_CHANGE_SHARDING_ATTRIBUTES); } } - TRI_json_t* patchedJson = TRI_MergeJson( - TRI_UNKNOWN_MEM_ZONE, old, json, !options.keepNull, options.mergeObjects); - TRI_FreeJson(zone, old); - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); + VPackBuilder patchedBuilder = arangodb::basics::VelocyPackHelper::merge( + old, slice, !options.keepNull, options.mergeObjects); - if (patchedJson == nullptr) { + VPackSlice patchedSlice = patchedBuilder.slice(); + if (patchedSlice.isNone()) { TRI_V8_THROW_EXCEPTION_MEMORY(); } - res = trx.updateDocument(key.get(), &mptr, patchedJson, policy, + res = trx.updateDocument(key.get(), &mptr, patchedSlice, policy, options.waitForSync, rid, &actualRevision); res = trx.finish(res); - TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, patchedJson); - if (res != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION(res); } diff --git a/arangod/VocBase/ExampleMatcher.cpp b/arangod/VocBase/ExampleMatcher.cpp index 9bfec55842..8de11a4806 100644 --- a/arangod/VocBase/ExampleMatcher.cpp +++ b/arangod/VocBase/ExampleMatcher.cpp @@ -31,6 +31,9 @@ #include "V8Server/v8-vocbaseprivate.h" #include "VocBase/VocShaper.h" +#include +#include + using namespace arangodb; using namespace arangodb::basics; @@ -231,6 +234,85 @@ void ExampleMatcher::fillExampleDefinition( } } +void ExampleMatcher::fillExampleDefinition( + VPackSlice const& example, CollectionNameResolver const* resolver, + ExampleDefinition& def) { + if (example.isString()) { + // Example is an _id value + std::string tmp = example.copyString(); + char const* _key = strchr(tmp.c_str(), '/'); + if (_key != nullptr) { + _key += 1; + def._internal.insert( + std::make_pair(internalAttr::key, DocumentId(0, _key))); + return; + } + THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND); + } + TRI_ASSERT(example.isObject()); + + size_t n = static_cast(example.length()); + + def._pids.reserve(n); + def._values.reserve(n); + + try { + for (auto const& it : VPackObjectIterator(example)) { + TRI_ASSERT(it.key.isString()); + std::string key = it.key.copyString(); + auto pid = _shaper->lookupAttributePathByName(key.c_str()); + if (pid == 0) { + // Internal attributes do have pid == 0. + if (key.at(0) != '_') { + // no attribute path found. this means the result will be empty + THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND); + } + if (!it.value.isString()) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR); + } + std::string keyVal = it.value.copyString(); + if (key == TRI_VOC_ATTRIBUTE_KEY) { + def._internal.insert( + std::make_pair(internalAttr::key, DocumentId(0, keyVal))); + } else if (key == TRI_VOC_ATTRIBUTE_REV) { + def._internal.insert( + std::make_pair(internalAttr::rev, DocumentId(0, keyVal))); + } else { + std::string colName = keyVal.substr(0, keyVal.find("/")); + keyVal = keyVal.substr(keyVal.find("/") + 1, keyVal.length()); + if (TRI_VOC_ATTRIBUTE_ID == key) { + def._internal.insert(std::make_pair( + internalAttr::id, + DocumentId(resolver->getCollectionId(colName), keyVal))); + } else if (TRI_VOC_ATTRIBUTE_FROM == key) { + def._internal.insert(std::make_pair( + internalAttr::from, + DocumentId(resolver->getCollectionId(colName), keyVal))); + } else if (TRI_VOC_ATTRIBUTE_TO == key) { + def._internal.insert(std::make_pair( + internalAttr::to, + DocumentId(resolver->getCollectionId(colName), keyVal))); + } else { + // no attribute path found. this means the result will be empty + THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND); + } + } + } else { + def._pids.push_back(pid); + auto value = TRI_ShapedJsonVelocyPack(_shaper, it.value, false); + + if (value == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND); + } + def._values.push_back(value); + } + } + } catch (std::bad_alloc const&) { + ExampleMatcher::cleanup(); + throw; + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief Constructor using a v8::Object example //////////////////////////////////////////////////////////////////////////////// @@ -331,6 +413,55 @@ ExampleMatcher::ExampleMatcher(TRI_json_t const* example, VocShaper* shaper, } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Constructor using a VelocyPack object +/// Note: allowStrings is used to define if strings in example-array +/// should be matched to _id +//////////////////////////////////////////////////////////////////////////////// + +ExampleMatcher::ExampleMatcher(VPackSlice const& example, VocShaper* shaper, + CollectionNameResolver const* resolver, + bool allowStrings) + : _shaper(shaper) { + if (example.isObject() || example.isString()) { + ExampleDefinition def; + try { + ExampleMatcher::fillExampleDefinition(example, resolver, def); + } catch (...) { + CleanupShapes(def._values); + ExampleMatcher::cleanup(); + throw; + } + definitions.emplace_back(std::move(def)); + } else if (example.isArray()) { + for (auto const& e : VPackArrayIterator(example)) { + ExampleDefinition def; + if (!allowStrings && e.isString()) { + // We do not match strings in Array + continue; + } + try { + ExampleMatcher::fillExampleDefinition(e, resolver, def); + definitions.emplace_back(std::move(def)); + } catch (arangodb::basics::Exception& e) { + if (e.code() != TRI_RESULT_ELEMENT_NOT_FOUND) { + CleanupShapes(def._values); + ExampleMatcher::cleanup(); + throw; + } + // Result not found might happen. Ignore here because all other elemens + // might be matched. + } + } + if (definitions.empty()) { + // None of the given examples could ever match. + // Throw result not found so client can short circuit. + THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND); + } + } +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief Checks if the given mptr matches the examples in this class //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/VocBase/ExampleMatcher.h b/arangod/VocBase/ExampleMatcher.h index 388af5fb2d..39aef54b72 100644 --- a/arangod/VocBase/ExampleMatcher.h +++ b/arangod/VocBase/ExampleMatcher.h @@ -33,6 +33,10 @@ class VocShaper; namespace arangodb { +namespace velocypack { +class Slice; +} + class ExampleMatcher { struct DocumentId { TRI_voc_cid_t cid; @@ -60,6 +64,10 @@ class ExampleMatcher { arangodb::CollectionNameResolver const* resolver, ExampleDefinition& def); + void fillExampleDefinition(arangodb::velocypack::Slice const& example, + arangodb::CollectionNameResolver const* resolver, + ExampleDefinition& def); + void fillExampleDefinition(v8::Isolate* isolate, v8::Handle const& example, v8::Handle const& names, size_t& n, @@ -75,6 +83,10 @@ class ExampleMatcher { ExampleMatcher(TRI_json_t const* example, VocShaper* shaper, arangodb::CollectionNameResolver const* resolver); + ExampleMatcher(arangodb::velocypack::Slice const& example, VocShaper* shaper, + arangodb::CollectionNameResolver const* resolver, + bool allowStrings); + ~ExampleMatcher() { cleanup(); } bool matches(TRI_voc_cid_t cid, TRI_doc_mptr_t const* mptr) const; diff --git a/arangod/VocBase/KeyGenerator.cpp b/arangod/VocBase/KeyGenerator.cpp index 8ceb34ec52..3c90878b03 100644 --- a/arangod/VocBase/KeyGenerator.cpp +++ b/arangod/VocBase/KeyGenerator.cpp @@ -70,7 +70,7 @@ KeyGenerator::KeyGenerator(bool allowUserKeys) KeyGenerator::~KeyGenerator() {} //////////////////////////////////////////////////////////////////////////////// -/// @brief get the generator type from JSON +/// @brief get the generator type from VelocyPack //////////////////////////////////////////////////////////////////////////////// KeyGenerator::GeneratorType KeyGenerator::generatorType( diff --git a/arangod/VocBase/KeyGenerator.h b/arangod/VocBase/KeyGenerator.h index 731ee95b58..c8ca27043f 100644 --- a/arangod/VocBase/KeyGenerator.h +++ b/arangod/VocBase/KeyGenerator.h @@ -76,7 +76,7 @@ class KeyGenerator { static void Initialize(); ////////////////////////////////////////////////////////////////////////////// - /// @brief get the generator type from JSON + /// @brief get the generator type from VelocyPack ////////////////////////////////////////////////////////////////////////////// static GeneratorType generatorType(arangodb::velocypack::Slice const&); diff --git a/arangod/VocBase/shaped-json.cpp b/arangod/VocBase/shaped-json.cpp index af668cbd11..8ec7839111 100644 --- a/arangod/VocBase/shaped-json.cpp +++ b/arangod/VocBase/shaped-json.cpp @@ -2123,6 +2123,17 @@ TRI_json_t* TRI_JsonShapedJson(VocShaper* shaper, return dst; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief converts a shaped json object into a VelocyPack Object +/// NOTE: Transforms via TRI_json_t. +//////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr TRI_VelocyPackShapedJson( + VocShaper* shaper, TRI_shaped_json_t const* shaped) { + std::unique_ptr tmp(TRI_JsonShapedJson(shaper, shaped)); + return arangodb::basics::JsonHelper::toVelocyPack(tmp.get()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief prints a shaped json to a string buffer, without the outer braces /// this can only be used to stringify shapes of type array diff --git a/arangod/VocBase/shaped-json.h b/arangod/VocBase/shaped-json.h index 4b7c677bfe..d241d22ad7 100644 --- a/arangod/VocBase/shaped-json.h +++ b/arangod/VocBase/shaped-json.h @@ -30,6 +30,7 @@ namespace arangodb { namespace velocypack { +class Builder; class Slice; } } @@ -901,6 +902,14 @@ TRI_shaped_json_t* TRI_ShapedJsonJson(VocShaper*, TRI_json_t const*, bool); TRI_json_t* TRI_JsonShapedJson(VocShaper*, TRI_shaped_json_t const*); +//////////////////////////////////////////////////////////////////////////////// +/// @brief converts a shaped json object into a VelocyPack Object +/// NOTE: Transforms via TRI_json_t. +//////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr TRI_VelocyPackShapedJson( + VocShaper*, TRI_shaped_json_t const*); + //////////////////////////////////////////////////////////////////////////////// /// @brief prints a shaped json to a string buffer, without the outer braces /// this can only be used to stringify shapes of type array diff --git a/arangod/Wal/LogfileManager.cpp b/arangod/Wal/LogfileManager.cpp index 404933d865..948cb4deef 100644 --- a/arangod/Wal/LogfileManager.cpp +++ b/arangod/Wal/LogfileManager.cpp @@ -24,11 +24,9 @@ #include "LogfileManager.h" #include "Basics/files.h" #include "Basics/hashes.h" -#include "Basics/json.h" #include "Basics/Logger.h" #include "Basics/Exceptions.h" #include "Basics/FileUtils.h" -#include "Basics/JsonHelper.h" #include "Basics/MutexLocker.h" #include "Basics/ReadLocker.h" #include "Basics/StringUtils.h" diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js index 004f26f4ca..0b03d2d333 100644 --- a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js +++ b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js @@ -406,15 +406,15 @@ }); if (found) { - this.deleteAardvarkJob(aardvark.id); - } - else { array.push({ collection: aardvark.collection, id: aardvark.id, type: aardvark.type }); } + else { + window.arangoHelper.deleteAardvarkJob(aardvark.id); + } } }); } diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js.gz b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js.gz index e0a932e871..0e7730d156 100644 Binary files a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js.gz and b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js.gz differ diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css index f26a8f942f..76b33f6f36 100644 --- a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css +++ b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css @@ -1,4 +1,4 @@ @charset "UTF-8";.fa.fa-pull-left,.fa.pull-left{margin-right:.3em}.fa,.fa-stack{display:inline-block}.clusterDownBtn,.clusterDownBtn button,.fa-fw,.fa-li,.fa-stack-1x,.fa-stack-2x,.footer,.modal-body th .valueCell,.modal-body th th.actionCell,.modal-body th th.keyCell,.waitModal,div.toolbox div.gv_action_button{text-align:center}.page-title span,.pingback a.url,body,input,textarea{font-family:'Open Sans',sans-serif!important;font-weight:400}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;src:local("Open Sans Light"),local("OpenSans-Light"),url(../fonts/opensans/OpenSansLight.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;src:local("Open Sans"),local("OpenSans"),url(../fonts/opensans/OpenSans.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:700;src:local("Open Sans Bold"),local("OpenSans-Bold"),url(../fonts/opensans/OpenSansBold.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;src:local("Open Sans Light Italic"),local("OpenSansLight-Italic"),url(../fonts/opensans/OpenSansLightItalic.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;src:local("Open Sans Italic"),local("OpenSans-Italic"),url(../fonts/opensans/OpenSansItalic.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:700;src:local("Open Sans Bold Italic"),local("OpenSans-BoldItalic"),url(../fonts/opensans/OpenSansBoldItalic.woff) format("woff")}/*! * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome/fontawesome-webfont.eot?v=4.4.0);src:url(../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.4.0) format("embedded-opentype"),url(../fonts/fontawesome/fontawesome-webfont.woff2?v=4.4.0) format("woff2"),url(../fonts/fontawesome/fontawesome-webfont.woff?v=4.4.0) format("woff"),url(../fonts/fontawesome/fontawesome-webfont.ttf?v=4.4.0) format("truetype"),url(../fonts/fontawesome/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.modal-body,button{font-family:'Open Sans',sans-serif!important}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa.fa-pull-right,.fa.pull-right{margin-left:.3em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right,.pull-right{float:right}.contentDiv li,.dashboard-bar-chart-container,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage,.dashboard-full-width-chart,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart,.dashboard-half-height-legend,.dashboard-large-chart,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-legend,.dashboard-medium-chart,.dashboard-medium-chart .dashboard-interior-chart,.dashboard-small-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart,.dashboard-sub-bar,.dashboard-sub-bar .dashboard-sub-bar-title,.dashboard-tendency-container,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar,.dashboard-title-bar .dashboard-half-title-bar,.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.machineClass,.modal-chart-detail,.modal-chart-detail .modal-body,.modal-chart-detail .modal-dashboard-legend,.modal-chart-detail .modal-inner-detail,.navlist li,.navlogo,.pull-left,.scenarioMachine,.script-dropdown-menu,.user-dropdown-menu,a.button-gui,a.headerButton,div .bigtile,div .bigtile a span.add-Icon,div .tile,div .tile a span.add-Icon,div.centralContent,div.dropdownInner ul,div.footer-center,div.footer-left,div.footer-left p{float:left}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.dashboard-sub-bar-menu,.headerBar>div.headerButtonBar,.navmenu,.search-field,div .bigtile .iconSet span,div .tile .iconSet span,div.footer-right,div.footer-right p,ul.headerButtonList li{float:right}.dashboard-bar-chart-container .dashboard-bar-chart:after,.dashboard-medium-chart .dashboard-medium-chart-inner:after,.dashboard-medium-chart .dashboard-medium-chart-menu:after,.dashboard-row:after,.dashboard-sub-bar:after,.dashboard-tendency-container .dashboard-tendency-chart:after,.detail-chart:after,.headerBar>div.headerButtonBar:after,.machineClass:after,.resizecontainer:after,.scenarioSingleMachine:after,.tileList:after{clear:both;content:'.';display:block;font-size:0;height:0;visibility:hidden}.addButton,.arangoicon,.clusterDownBtn button,.contentDiv .icon,.deleteButton,.gv-search-submit-icon,.icon-info-sign,.scenarioImage,.script-dropdown-menu .dropdown-item,.search-submit-icon,a.button-gui,a.headerButton,div .bigtile,div .bigtile .iconSet span,div .bigtile a span.icon,div .bigtile a svg,div .tile .iconSet span,div .tile a span.icon,div .tile a svg,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,div.toolbox div.gv_action_button{cursor:pointer}.navbar,footer.footer{background-color:rgba(245,248,240,.95);color:#fff;left:0;position:fixed;right:0;width:100%;z-index:1000}.button-danger{background-color:#da4f49}.button-danger:focus,.button-danger:hover{background-color:#be342e}.deleteButton,a.danger.coordinator,a.danger.dbserver{color:#da4f49}.deleteButton:focus,.deleteButton:hover,a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{color:#be342e}a.danger.coordinator,a.danger.dbserver{fill:#da4f49}a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{fill:#be342e}.button-success{background-color:#8aa051}.button-success:focus,.button-success:hover{background-color:#788f3d}.addButton,a.success.coordinator,a.success.dbserver{color:#8aa051}.addButton:focus,.addButton:hover,a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{color:#788f3d}a.success.coordinator,a.success.dbserver{fill:#8aa051}a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{fill:#788f3d}.button-warning{background-color:#faa732}.button-warning:focus,.button-warning:hover{background-color:#f89406}a.warning.coordinator,a.warning.dbserver{color:#faa732;fill:#faa732}a.warning.coordinator:focus,a.warning.coordinator:hover,a.warning.dbserver:focus,a.warning.dbserver:hover{color:#f89406;fill:#f89406}.button-close,.button-neutral{background-color:#8f8d8c}.button-close:focus,.button-close:hover,.button-neutral:focus,.button-neutral:hover{background-color:#736b68}.dashboard-sub-bar-menu{color:#8f8d8c}.dashboard-sub-bar-menu:focus,.dashboard-sub-bar-menu:hover{color:#736b68}.button-primary{background-color:#564e4a}.button-primary:focus,.button-primary:hover{background-color:#3a322e}.button-header,a.button-gui,a.headerButton{background-color:#fff;border:1px solid #fff;color:#555}.button-header:focus,.button-header:hover,a.button-gui:focus,a.button-gui:hover,a.headerButton:focus,a.headerButton:hover{background-color:#8aa051;border:1px solid #8aa051;color:#fff}.button-notification{background-color:#faa020}.button-notification:focus,.button-notification:hover{background-color:#f87c0f}.button-inactive,.button-inactive:focus,.button-inactive:hover,[class*=' button-']:disabled,[class*=' button-']:focus:disabled,[class*=' button-']:hover:disabled,[class^=button-]:disabled,[class^=button-]:focus:disabled,[class^=button-]:hover:disabled,button.disabled,button.disabled:focus,button.disabled:hover{background-color:#d3d3d3}a.headerButton.disabled,a.headerButton.disabled:focus,a.headerButton.disabled:hover,a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{color:#d3d3d3}a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{fill:#d3d3d3}div.queryline .fa.fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:relative;right:21px;top:-1px}div.queryline .fa.fa-search:hover{cursor:pointer;opacity:1}.modal-body .select2-choices input,.modal-body input,.modal-body select,.modal-body textarea,.navbar .arango-collection-select,div.queryline input,div.queryline select,input.search-input{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#fff!important;border:1px solid rgba(140,138,137,.25);box-shadow:none;outline:transparent 0}.modal-body input:focus,.modal-body select:focus,.modal-body textarea:focus,.navbar .arango-collection-select:focus,div.queryline input:focus,div.queryline select:focus,input.search-input:focus{border-color:#999;box-shadow:none;outline:transparent 0}.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.script-dropdown-menu,.user-dropdown-menu{background-color:#f5f8f0;border-color:#666;border-radius:3px;border-style:solid;border-width:1px;box-shadow:none;display:none;list-style:none;margin:5px 0 0;padding:5px 0;position:absolute;right:0;top:80%;z-index:1000}.script-dropdown-menu .dropdown-item a,.tab{display:block}.dropdown-toolbar li,.gv-dropdown-menu li,.link-dropdown-menu li,.script-dropdown-menu li,.user-dropdown-menu li{line-height:23px;white-space:nowrap;width:100%}.dropdown-toolbar .dropdown-header,.gv-dropdown-menu .dropdown-header,.link-dropdown-menu .dropdown-header,.script-dropdown-menu .dropdown-header,.user-dropdown-menu .dropdown-header{color:#999;font-size:15px;font-weight:600;font-variant:small-caps;padding:0}.dropdown-toolbar .dropdown-header:hover,.gv-dropdown-menu .dropdown-header:hover,.link-dropdown-menu .dropdown-header:hover,.script-dropdown-menu .dropdown-header:hover,.user-dropdown-menu .dropdown-header:hover{cursor:default}.dropdown-toolbar .divider,.gv-dropdown-menu .divider,.link-dropdown-menu .divider,.script-dropdown-menu .divider,.user-dropdown-menu .divider{background-color:#666;height:1px;margin:10px 0 5px}.dropdown-toolbar a,.gv-dropdown-menu a,.link-dropdown-menu a,.script-dropdown-menu a,.user-dropdown-menu a{color:#fff;padding:0 20px}.navbar{-webkit-font-smoothing:subpixel-antialiased;height:44px;margin-bottom:3px;padding-top:6px;top:0}.navbar .no-left-margin{border:0;margin-left:0}.navbar .no-left-margin.hover{background-color:transparent}.navbar .arangodbLogo{height:auto;margin-left:-5px;margin-top:-1px;width:40%}.navbar .arango-collection-select{position:relative;right:-22px;top:4px}.navbar .nav .dropdown .active>.dropdown-toggle,.navbar .nav .dropdown .open.active>.dropdown-toggle,.navbar .nav .dropdown .open>.dropdown-toggle{background:#788f3d}.navbar .nav>.active>a{-webkit-box-shadow:0 0 0 transparent inset;-moz-box-shadow:0 0 0 transparent inset;box-shadow:0 0 0 transparent inset;background-color:#fff;color:#000}.navbar .nav>li>a:focus{background-color:#fff}.navbar .nav>li>a:hover{background-color:#000;color:#686766}.navlist .dropdown-item:hover a,.navlist>.active a,.navlist>.active:hover a,.navlist>li:hover a{color:#000}.navlogo{margin-left:5px;margin-right:-3px;padding-top:3px}.navlist{list-style:none}.navlist>li{height:39px}.navlist li{border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;margin-left:7px}.navlist li.dropdown:hover{background-color:#fff;border-bottom-left-radius:0;border-bottom-right-radius:0;border-left:1px solid rgba(0,0,0,.2);border-right:1px solid rgba(0,0,0,.2);border-top:1px solid rgba(0,0,0,.2)}.navlist li.dropdown:hover a{border-bottom:2px solid #fff}.navlist li.divider,.navlist li.navbar-spacer{border:0}.navlist li.divider{background-color:rgba(0,0,0,.2)}.navlist li.navbar-spacer{background-color:#a0a0a0;height:21px;margin-top:9px;width:1px}.navlist li.navbar-spacer.big{margin-left:15px;margin-right:15px}.navlist li.navbar-spacer.med{margin-left:5px;margin-right:5px}.navlist .dropdown-item,.script-dropdown-menu .dropdown-item{margin-left:0}.navlist li.navbar-spacer:hover{background-color:#a0a0a0}.navlist .active .tab{border-bottom:2px solid #8aa051;padding-bottom:4px}.navlist>.active{background-color:transparent}.navlist>.active:hover{background-color:#fff}.navlist .dropdown-item:hover,.navlist>li:hover{background-color:#fff;border-radius:3px}.navlist .dropdown-item a{border-bottom:0;display:block;font-size:11pt}.navlist .dropdown-item a:hover{background-color:#dee9cf;color:#686766}.tab{color:#686766;font-size:12pt;font-weight:100;padding:9px 5px 10px}.tab.userImg{padding-bottom:5px}.dropdown-item a{border-bottom:0!important;font-weight:300}.dropdown-toolbar,div.headerBar,div.headerDropdown{border:1px solid rgba(140,138,137,.25)}.dropdown-toolbar li a,footer.footer p{font-weight:100}.dropdown-toolbar{background-color:#fff!important}.dropdown-toolbar li a:hover{background:0 0;background-color:#dee9cf!important;color:#000!important}.link-dropdown-menu,.user-dropdown-menu{background-color:#fff;border:1px solid rgba(0,0,0,.2);border-top-right-radius:0;margin-right:-1px;margin-top:7px;z-index:-10}.link-dropdown-menu .dropdown-item,.user-dropdown-menu .dropdown-item{border-left:0;border-right:0}.script-dropdown-menu .dropdown-item a:hover{color:#fff}.script-dropdown-menu .dropdown-item:hover{background-color:#8aa051}.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:rgba(0,0,0,.7);border:1px solid #c2c2c2;margin-right:-20px;margin-top:6px}.gv-dropdown-menu:after{border-bottom-color:#fff}.gv-dropdown-menu li:hover{background-color:#fff;background-image:none}.gv-dropdown-menu li a{padding:0}.gv-dropdown-menu li a label{color:#fff;padding-left:5px}.gv-dropdown-menu li a:focus{background-color:#8aa051!important;background-image:none}#arangoCollectionSelect{display:none;float:right;margin-bottom:0;margin-right:15px;padding-bottom:0}.caret{border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #686766;content:'';display:inline-block;height:0;vertical-align:top;width:0}.applications-menu{display:block}.arango-logo{height:34px;padding:0!important}.arango-logo img{margin-left:22px}.footer{bottom:0;font-size:14px;left:0;position:fixed;right:0;z-index:1000}.modal,.select2-drop-active{z-index:9999999}footer.footer{bottom:0;height:40px}footer.footer p{font-size:10pt;margin-bottom:0;padding-bottom:10px;padding-top:10px}div.footer-left{background:none;color:#686766;width:45%}div.footer-left .social-icons{margin-top:5px}div.footer-left .social-icons a{display:block;float:left;height:25px;width:25px}div.footer-left .social-icons p{background:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;height:25px;margin-right:10px;padding:0;width:25px}div.footer-left .social-icons p:hover{background:#8aa051;cursor:pointer}div.footer-left .social-icons p:hover i{color:#fff}div.footer-left .social-icons i{color:#000;margin-top:6px;position:absolute}.addButton,.deleteButton{position:relative;font-size:22px}div.footer-left .social-icons i.fa-twitter{margin-left:-5px}div.footer-left .social-icons i.fa-envelope{margin-left:-19px}div.footer-left .social-icons i.fa-google{margin-left:-17px;margin-top:7px}div.footer-left .social-icons i.fa-stack-overflow{margin-left:-17px}div.footer-center{background:none;color:#686766;width:10%}div.footer-center i{background-color:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;margin-left:1px;padding:6px 2px;width:20px}div.footer-center i:hover{background-color:#8aa051;color:#fff}div.footer-center p{padding-top:5px}div.footer-center p:hover{cursor:pointer}[class*=' button-']:disabled,[class^=button-]:disabled,a.headerButton.disabled,button.disabled{cursor:not-allowed}div.footer-right{background:none;color:#686766;width:45%}div.footer-right p{color:#fff}div.footer-right i{color:#da4f49;font-size:18px}div.footer-right a{color:#686766;margin-left:5px;position:relative;top:-1px}div.footer-right .isOnline{color:#8aa051!important}.button-close,.button-danger,.button-header,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;font-size:14px;font-weight:300!important}.button-close,.button-danger,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{border:0;color:#fff;margin-left:10px;padding:5px 16px}.button-header{margin-top:5px}.addButton{margin-right:7px;margin-top:2px}.deleteButton{padding-right:3px;top:3px}#closeBtnInfoView{margin-left:0!important}button.btn-server{width:120px}button.gv-zoom-btn{background-size:14px 14px;height:14px;vertical-align:baseline;width:14px}button.gv-zoom-btn.btn-zoom-right{border:0;box-shadow:none;right:0;top:13px}button.gv-zoom-btn.pan-right{background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-right:hover{background:inherit;background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-left{background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-left:hover{background:inherit;background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-top{background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-top:hover{background:inherit;background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-bottom{background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.pan-bottom:hover{background:inherit;background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.btn-zoom{height:14px;margin:0;padding:0;position:absolute;width:16px}button.gv-zoom-btn.btn-zoom-top{border:0;box-shadow:none;left:13px;top:1}button.gv-zoom-btn.btn-zoom-left{border:0;box-shadow:none;left:0;top:13px}button.gv-zoom-btn.btn-zoom-bottom{border:0;box-shadow:none;left:13px;top:25px}button.gv-icon-btn{-moz-border-radius:0!important;-webkit-border-radius:0!important;border-radius:0!important;background-size:36px 36px;height:36px;width:36px}button.gv-icon-btn.active{background-color:#8aa051}button.gv_dropdown_entry{height:30px;margin:4px 4px 4px 30px;width:160px}button.gv_context_button{width:65px}button.large-distance{margin-left:12px}button.short-distance{margin-left:6px}button.shutdown{margin-top:6px;padding:3px 14px}button.graphViewer-icon-button{background-color:transparent;border:0;height:20px;margin-left:5px;margin-top:-2px;padding:0;width:20px}button.graphViewer-icon-button img{height:20px;padding-bottom:10px;width:20px}ul.headerButtonList{display:inline-block;margin-bottom:0;margin-left:0;padding-left:0!important}ul.headerButtonList li{display:inline}a.button-gui,a.headerButton{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;margin-left:5px;margin-right:5px}a.headerButton{margin-top:2px;position:relative}a.headerButton .fa,a.headerButton [class*=" icon_"],a.headerButton [class^=icon_]{display:block;height:23px;line-height:23px;position:static;right:0;text-align:center;top:0;width:27px}a.button-gui.button-gui-disabled,div.headerDropdown,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox{display:none}a.headerButton .icon_arangodb_arrowleft,a.headerButton .icon_arangodb_arrowright{font-weight:700}a.headerButton.activated{background-color:#788f3d;border:1px solid #788f3d;color:#fff}div.toolbox,div.toolbox div.gv_action_button{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#fff}a.headerButton.activated:hover{background-color:#fff;color:#788f3d}div.toolbox{border-radius:3px;border:1px solid rgba(140,138,137,.25);margin-right:5px;margin-top:-3px;padding-bottom:5px;padding-top:5px;position:absolute}div.toolbox div.gv_action_button{border-radius:3px;color:#555;height:30px;margin:5px;position:relative;width:30px}div.toolbox div.gv_action_button.active{background-color:#8aa051;color:#fff}div.toolbox div.gv_action_button:first-child{margin-top:0}div.toolbox div.gv_action_button:last-child{margin-bottom:0}h6.gv_button_title,h6.gv_icon_icon{left:0;margin:0;position:absolute;right:0}h6.gv_icon_icon{font-size:22px;left:1px;top:4px}h6.gv_button_title{bottom:1px;display:none}.btn-icon{background-color:#383434;padding:4px}.gv-icon-small{background-size:16px 16px;height:16px!important;width:16px!important}.gv-icon-small.delete{background-image:url(../img/icon_delete.png)}.gv-icon-small.add{background-image:url(../img/plus_icon.png)}a.pagination-button,ul.arango-pagination a{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.badge,.btn,.label{text-shadow:none!important}.navbar-inner,.thumbnail{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0}.modal-body th.actionCell>button{margin-top:-12px}.btn-old-padding{padding-bottom:4px!important;padding-top:4px!important}button.btn-overview,button.btn-server{margin:5px}a.button-gui{height:auto;margin-bottom:0;margin-top:0;padding-bottom:1px;padding-top:1px;position:absolute;right:2px;text-decoration:none!important;top:2px;width:auto}.clusterDownBtn{padding-bottom:10px;padding-top:10px}.clusterDownBtn button{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#f1f1f1;border:1px solid rgba(0,0,0,.1875);color:#333;font-size:20px;font-weight:300;margin:0;padding:12px 18px;text-decoration:none!important;width:250px}.clusterDownBtn button:hover{background-color:#e8e8e8;color:#4a6c30;-webkit-transition-delay:0;-webkit-transition-duration:.2s;-webkit-transition-property:all;-webkit-transition-timing-function:ease-in}.clusterDownBtn button.green{background-color:#617e2b;color:#fff}.clusterDownBtn button.green:hover{background-color:#8ba142}.bottomButtonBar{background-color:#fff;border-top:1px solid rgba(104,103,102,.1);height:30px;padding:10px}.clusterInfoIcon{float:left;padding-left:5px;padding-top:2px}.waitModal.icon{font-size:100px;height:120px}.waitModal.message{font-size:20px}.icon_arangodb_info{color:#333;font-size:23px}li a [class*=" icon_arangodb"],li a [class^=icon_arangodb]{font-size:18px;position:absolute;right:4px;top:2px}.fa-minus-circle{color:#da4f49;font-size:14pt}.fa-minus-circle:hover{cursor:pointer}div.headerDropdown{background-color:#fff;border-radius:3px;clear:both;padding:10px;position:relative;width:auto}div.headerDropdown.smallDropdown .dropdownInner{min-height:20px}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.dropdown-title{margin-bottom:10px}div.dropdownInner{-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;min-height:125px;position:relative;width:auto}div.dropdownInner .nav-header{font-size:10pt}div.dropdownInner>.nav-header{color:#000;font-size:10pt;font-weight:400}div.dropdownInner>label{color:#000;font-weight:300}div.dropdownInner ul{border-left:1px solid rgba(140,138,137,.25);display:inline;list-style-type:none;margin-top:10px;min-height:105px;width:230px}div.dropdownInner ul:first-of-type,div.queryline input[type=file]{border:0}div.dropdownInner ul label{color:#000;padding-left:20px}div.dropdownInner ul li .fa{color:#999;margin-right:5px}div.dropdownInner ul li .fa.fa-square-o{margin-left:1px;margin-right:6px}div.dropdownInner ul li .fa.fa-check-circle-o,div.dropdownInner ul li .fa.fa-check-square-o,div.dropdownInner ul li .fa.fa-dot-circle-o{color:#8aa051}div.queryline{color:#000;height:35px}div.queryline .textDiv{margin-right:10px;margin-top:4px}div.queryline input,div.queryline select{margin-bottom:5px}div.queryline.querylineAdd span{color:#fff;padding-left:10px;position:relative;top:-21px}div.queryline .removeFilterItem i{margin-left:5px!important;margin-top:0!important}div.queryline div.searchByAttribute{margin-left:6px;margin-right:6px;position:relative}div.queryline div.searchByAttribute>ul.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:#fff;color:#fff;display:none;left:0;position:absolute;top:20px;width:247px}div.dropdownImport{background-color:#fff;border-radius:3px;display:none;position:relative;padding:10px 10px 5px}div.dropdownImport input{line-height:0;margin-bottom:-15px;margin-top:5px}select.filterSelect{color:#00f;margin-left:10px;margin-right:10px;width:100px}#filterHeader button{float:right;margin-left:10px!important;margin-top:1px}div.input-append button.gv_example_toggle{-moz-border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;background-color:#8f8d8c;height:30px;margin-left:-1px;padding-left:10px;padding-right:10px;padding-top:12px;vertical-align:top}div.input-append button.gv_example_toggle:hover{background-color:#8aa051}div.headerBar,div.headerBar .infoField{background-color:#fff;padding-left:5px;padding-right:5px}.searchEqualsLabel{margin-left:6px;margin-right:6px}img.gv-throbber{background-image:url(../img/swagger/throbber.gif)}span.gv_caret{border-top:5px solid #fff;margin-top:2px!important}input.search-input{height:14px;line-height:18px;margin-right:-1px;margin-top:6px;width:120px}.search-field{margin-left:10px}.search-field .fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:absolute;right:9px;top:9px}.search-field .fa-search:hover{cursor:pointer;opacity:1}.gv-search-submit-icon,.search-submit-icon{background-image:url(../img/enter_icon.png);background-size:14px;height:14px;margin-left:-18px;opacity:.2;position:absolute;width:14px}.gv-search-submit-icon:hover,.search-submit-icon:hover{opacity:.8}.search-submit-icon{margin-top:11px}.gv-search-submit-icon{margin-top:6px}div.headerBar{border-radius:3px;color:#fff;font-size:16px;height:36px;margin-bottom:5px;margin-top:15px;position:relative}div.headerBar .infoField{border:1px solid rgba(140,138,137,.25);border-radius:3px!important;color:#000;float:right;font-size:12px;margin-right:7px;margin-top:7px}div.headerBar .infoField .fa{cursor:pointer;margin-left:5px}div.headerBar input[type=checkbox].css-checkbox{display:none}div.headerBar input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;cursor:pointer;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerBar input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.headerBar input[type=radio]{display:none}div.headerBar input[type=radio] label span{background:url(../img/check_radio_sheet.png) -38px top no-repeat;cursor:pointer;display:inline-block;height:19px;margin:-1px 4px 0 0;vertical-align:middle;width:19px}#transparentHeader input[type=checkbox].css-checkbox,.lineGraph .many .dygraph-legend>span,.modal-delete-confirmation{display:none}div.headerBar input[type=radio]:checked+label span{background:url(../img/check_radio_sheet.png) -57px top no-repeat}.headerButtonList a.error{color:#da4f49}.headerButtonList a.error:hover{background-color:#da4f49;border-color:#da4f49;color:#fff}.headerBar a.arangoHeader{color:#000;font-size:13pt;font-weight:100;left:0;position:relative;top:7px}.headerBar>div.headerButtonBar{margin:4px 0;margin-bottom:0!important}.breadcrumb{background:0 0;border:0;border-radius:0;padding:7px 0}.breadcrumb .disabledBread{color:#666;float:left;font-size:13pt;font-weight:100;padding-right:5px;position:relative}.breadcrumb .disabledBread i{font-size:10pt;margin-left:10px}.breadcrumb .activeBread{color:#8aa051;float:left;font-size:13pt;font-weight:100}.arangoHeader{font-weight:400}.checkboxLabel{margin-top:4px;padding-left:0}.css-label{background-image:url(../img/dark-check-green.png)}.css-label-round{background-image:url(../img/dark-check-green-round.png)}.modal-dashboard-header,.modal-header{background-color:#fff;border-bottom:0!important;border-radius:3px;margin-top:5px;padding-left:5px;padding-right:10px;padding-top:4px}.modal-dashboard-header .arangoHeader,.modal-header .arangoHeader{color:#000;font-size:13pt;font-weight:100;left:5px;position:relative;top:2px}.modal-dashboard-header a,.modal-header a{top:2px!important}.modal-dashboard-header .close,.modal-header .close{color:#fff;font-weight:300;margin-top:2px;opacity:.5}.modal-dashboard-header .close:hover,.modal-header .close:hover{opacity:1}.modal-tabbar{border-bottom:1px solid #000}.modal-body{color:#736b68;font-size:14px;font-weight:300;max-height:410px}.modal-body .select2-choices{background-image:none!important;border:1px solid #999;border-radius:3px;-webkit-box-shadow:none;box-shadow:none}.modal-body .select2-choices input:active{-webkit-box-shadow:none;box-shadow:none;outline:0!important}.modal-body .select2-choices .select2-search-choice{margin:5px 0 3px 5px!important}.modal-body .select2-choices li{background-color:#fff!important;background-image:none!important;color:#000}.modal-body tr.first,.modal-body tr.last,.modal-body tr.middle{background-color:#f5f8f0}.modal-body .select2-choices li a{margin-left:1px;margin-top:-1px}.modal-body .select2-choices:active{border:1px solid #999;-webkit-box-shadow:none!important;box-shadow:none!important;outline:transparent!important}.modal-body .nav-tabs{margin-top:15px}.modal-body .nav-tabs>li>a:hover{border-color:#8c8a89}.modal-body input,.modal-body select,.modal-body textarea{margin-top:10px}.modal-body input[type=checkbox]{margin-bottom:10px}.modal-body input[type=text].invalid-input{border-color:rgba(234,23,23,.6)}.modal-body input[type=text].invalid-input:focus{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6)}.modal-body input[type=file]{line-height:17px}.modal-body tr.spacer{height:10px}.modal-body tr.first th:first-child{border-top-left-radius:3px}.modal-body tr.first th:last-child{border-top-right-radius:3px}.modal-body tr.middle{padding-left:10px;padding-right:10px}.modal-body tr.last th:first-child{border-bottom-left-radius:3px}.modal-body tr.last th:last-child{border-bottom-right-radius:3px}.modal-body tr.first th:first-child,.modal-body tr.last th:first-child,.modal-body tr.middle th:first-child{padding-left:10px}.modal-body tr.first th:last-child,.modal-body tr.last th:last-child,.modal-body tr.middle th:last-child{padding-right:10px}.modal-body th.actionCell{width:30px}.modal-body th.keyCell{width:170px}.modal-body th.keyCell input{width:150px}.modal-body th .valueCell{width:300px}.modal-body th .valueCell input{width:290px}.modal-body th .select2-container{margin-bottom:10px;margin-top:10px}.modal-body .icon-info-sign{margin-bottom:10px;margin-left:10px;opacity:.7;padding-bottom:5px}.modal-body .icon-info-sign:hover{opacity:1}.modal-body .icon_arangodb_info{color:#736b68;font-size:18px;margin-top:-10px;position:absolute;right:12px}.modal-body .icon_arangodb_info:hover{color:#000}.modal-body .collapse{margin-right:-14px;position:relative}.modal-body .accordion-inner{border-top:0;margin-left:0;padding-left:0;padding-right:0}.modal-body .accordion-toggle span .caret{border-top-color:#000;float:right;margin-top:5px}.modal-body .accordion-toggle.collapsed span .caret{-ms-transform:rotate(90deg);-webkit-transform:rotate(90deg);transform:rotate(90deg)}.modal-body input{width:384px}.modal-body select{width:398px}.modal-body .collectionTh{height:50px}.modal-body .tab-content{min-height:200px}.modal-body .tab-content .tab-pane{border-top:1px solid #666!important;margin-left:0!important;padding-top:10px}.modal-body .tab-content .tab-pane-modal{border-top:none!important}.modal-body .tab-content #appstore{max-height:290px}.modal-body .errorMessage{background-color:#fff;color:#da4f49;font-size:9pt;font-weight:400;margin-bottom:5px;margin-top:-9px;position:absolute}.modal-body .nav .tab-icon{margin-right:5px;margin-top:-3px;width:20px}.modal-text{font-weight:300;padding-bottom:3px;padding-top:3px}.modal-backdrop,.modal-backdrop.fade.in{opacity:.4}.modal{border:0!important;border-radius:3px!important;box-shadow:0;width:580px}.modal .fade.in{top:12.1%!important}.modal table tr:last-child{border-bottom:0!important}.waitModal{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:0 0;border:0;color:#fff}.waitModalBackdrop{opacity:.7!important}.modalTooltips span{color:#736b68;font-size:20px}.modalTooltips span:hover{color:#000}.gv-object-view{text-align:left;white-space:pre}.capitalize{text-transform:capitalize}.modal-footer{border-top:0!important;padding-right:17px}.modal-header{margin-left:5px;margin-right:5px}.modal-dashboard-header{margin-left:0;margin-right:0;padding-bottom:9px}.modal table tr,.thBorderBottom{border-bottom:1px solid #f7f3f2!important}.modal-delete-confirmation button{margin-right:10px;margin-top:-4px}.modal-delete-confirmation button .modal-confirm-delete{margin-right:-18px}.modal-delete-confirmation fieldset input{float:left}.modal-delete-confirmation fieldset label{float:left;margin-left:10px}.createModalDialog table{width:100%}.createModalDialog .collection-info-figures table{float:left;margin-left:0;margin-right:0;margin-top:0;min-width:200px;padding:3px;text-align:left}.createModalDialog .figures1,.createModalDialog .figures2{margin-bottom:20px;width:255px}.createModalDialog .figures2{margin-left:20px!important}.createModalDialog .figures3{margin-bottom:0;width:100%}.foxx-store-row .foxx-name{font-weight:700}.foxx-store-row .foxx-author{font-size:10pt;font-weight:300;margin-top:-4px}.foxx-store-row .foxx-version{font-weight:400}#new-app-mount{margin-right:24px;width:360px}#control_event_edge_delete_modal,#control_event_edge_edit_modal,#control_event_new_node_modal,#control_event_node_delete_modal,#control_event_node_edit_modal{margin-left:-320px;width:640px}.scenarioImage{height:70%;width:auto}svg.clusterChart{height:auto;margin:auto;width:auto}.lineGraph{position:absolute}.lineGraph .few .dygraph-legend>span.highlight{border:1px solid grey}.lineGraph .many .dygraph-legend>span.highlight{display:inline}a.coordinator,a.dbserver{color:#000;height:50px;position:absolute;top:10px;width:50px}a.coordinator h6.serverName,a.dbserver h6.serverName{bottom:0;font-size:11px;left:0;margin:0;position:absolute;right:0}a.coordinator.single{left:90px}a.coordinator.double{left:60px}a.dbserver.single{right:90px}a.dbserver.double{right:60px}.cluster-connection-check-success{color:#8aa051;margin-left:20px}.cluster-connection-check-fail{color:#da4f49;margin-left:20px}.cluster-unreachable-info{margin:0 auto;max-width:320px;padding-top:17px;text-align:center}.machineClass{background-color:#e1e1e1;margin-left:31px;margin-right:31px;padding:10px}.scenarioBox{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:rgba(0,0,0,.075);border:1px solid rgba(0,0,0,.19);height:65px;left:10px;margin-top:30px;position:absolute;right:10px;width:auto}.scenarioMachine,div .bigtile,div .tile{background-color:#fff;position:relative}.scenarioBox.bottomBox{bottom:30px}.scenarioBoxHeader{border-bottom:1px solid rgba(0,0,0,.19);height:18px;line-height:18px;margin-top:0;padding-bottom:0;text-align:center;width:auto}.scenarioBoxText{font-size:13px;font-weight:400;margin-top:17px;text-align:center;width:auto}.collectionName,div .bigtile .badge-success,div .tile .badge-success{font-weight:300}.scenarioMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;border:1px solid rgba(0,0,0,.19);height:257px;margin-right:17px;width:109px}.scenarioMachine:last-child{margin-right:0}.scenarioSingleMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background-color:#fff;border:1px solid rgba(0,0,0,.19)}.scenarioSingleMachine .scenarioMachine{border:1px solid transparent;height:238px}.bigtile.informationtile{cursor:auto}div .bigtile .collection-type-icon:hover,div .bigtile img:hover,div .bigtile:hover,div .tile .collection-type-icon:hover,div .tile img:hover,div .tile:hover{cursor:pointer}.informationText{background:#fff;font-size:12px;margin:10px;padding:5px;text-align:left}.tileList{margin-left:-6px;margin-right:-6px}.tileList legend{padding-left:5px}.tileList .tile:first-child a{opacity:.8}.tileList .tile:first-child a:hover{opacity:1}div .bigtile,div .tile{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border:1px solid #f5f8f0;border-radius:3px;font-size:14px;list-style:none;margin-bottom:13px;margin-left:6px;margin-right:6px;text-align:center;z-index:1}div .bigtile .warning-icons,div .tile .warning-icons{background-color:#da4f49;border-radius:3px;color:#fff;font-size:11px;height:17px;left:0;line-height:13px;margin-left:5px;margin-top:5px;padding-left:9px;padding-right:9px;position:absolute;top:0}div .bigtile a svg.icon,div .bigtile img.icon,div .tile a svg.icon,div .tile img.icon{height:50px;width:50px}div .bigtile .warning-icons .fa,div .tile .warning-icons .fa{font-size:11pt;margin-left:1px}div .bigtile .collection-type-icon,div .tile .collection-type-icon{color:#666;font-size:30pt;margin-top:12pt}div .bigtile img,div .tile img{position:relative}div .bigtile a span.add-Icon,div .tile a span.add-Icon{font-size:22px;margin-left:22px;margin-right:10px;margin-top:-5px;position:relative;right:4px;top:2px}div .bigtile a span.icon,div .tile a span.icon{font-size:50px}div .bigtile .tile-icon-svg,div .tile .tile-icon-svg{cursor:pointer;fill:#686766;height:50px;margin-left:90px;margin-top:10px;position:absolute;width:50px}div .bigtile .tile-icon,div .tile .tile-icon{color:#686766;font-size:50px;line-height:1.2}div .bigtile .icon_arangodb_edge5-2,div .tile .icon_arangodb_edge5-2{display:inline-block;position:relative;top:15px;-moz-transform:rotate(80deg);-o-transform:rotate(80deg);-webkit-transform:rotate(80deg)}div .bigtile h5,div .tile h5{background:#8c8a89;color:#fff;font-size:12px;margin:0;overflow:hidden!important;padding:4px 8px;text-overflow:ellipsis!important;white-space:nowrap!important}div .bigtile .tileSelects,div .tile .tileSelects{margin-left:40px;position:relative;z-index:9999}div .bigtile .tileSelects select,div .tile .tileSelects select{float:right;height:20px;margin-right:5px;margin-top:16px;width:70px}div .bigtile .fullBorderBox,div .tile .fullBorderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:100%;position:absolute;width:100%}div .bigtile .borderBox,div .tile .borderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:75px;position:absolute;width:224px}.collectionName,.dashboard-sub-bar{border-bottom-left-radius:3px;border-bottom-right-radius:3px}div .bigtile .iconSet,div .tile .iconSet{position:absolute;right:5px;top:5px}div .bigtile .iconSet span,div .tile .iconSet span{border-radius:3px;color:#666;font-size:18px;z-index:2;padding:2px 3px}div .bigtile .iconSet span:hover,div .tile .iconSet span:hover{background-color:#8aa051;color:#fff}div .bigtile .iconSet span.disabled,div .tile .iconSet span.disabled{cursor:default;opacity:.2}div .bigtile .iconSet span.disabled:hover,div .tile .iconSet span.disabled:hover{background-color:#fff;color:#000;cursor:default;opacity:.2}div .bigtile .unloaded div,div .tile .unloaded div{border-bottom:16px solid #ff8f35}div .bigtile .deleted div,div .tile .deleted div{border-bottom:16px solid #700}div .bigtile .tileBadge,div .tile .tileBadge{bottom:29px;font-size:11px;font-weight:300;position:absolute;right:0}div .bigtile .tileBadge button,div .tile .tileBadge button{margin-left:0;margin-right:5px}div .bigtile .tileBadge span,div .tile .tileBadge span{display:inline-block;line-height:15px}div .bigtile .tileBadge span .corneredBadge,div .tile .tileBadge span .corneredBadge{border-bottom-style:solid;border-bottom-width:17px;border-left:5px solid transparent;border-radius:3px;color:#fff;height:0;margin-bottom:4px;margin-right:5px;padding-left:1px;padding-right:6px}div .bigtile .tileBadge span .corneredBadge.loading,div .tile .tileBadge span .corneredBadge.loading{border-bottom-color:#ff8f35}div .bigtile .tileBadge span .corneredBadge.loaded,div .tile .tileBadge span .corneredBadge.loaded{border-bottom-color:#8aa051}div .bigtile .tileBadge span .corneredBadge.development,div .bigtile .tileBadge span .corneredBadge.unloaded,div .tile .tileBadge span .corneredBadge.development,div .tile .tileBadge span .corneredBadge.unloaded{border-bottom-color:#ff8f35}div .tile{height:100px;width:226px}div .tile-graph .tile-icon:hover{cursor:pointer}div .bigtile{height:309px;width:452px}div .bigtile .shardContainer{font-size:30px}div .bigtile .shardContainer span{padding:2px}.collectionName{bottom:0;left:0;position:absolute;right:0;text-align:left}.dashboard-bar-chart-container,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-medium-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-tendency-container{border-top-left-radius:3px;border-top-right-radius:3px}.dashboard-bar-chart-container:first-child,.dashboard-full-width-chart .dashboard-full-width-chart-inner:first-child,.dashboard-large-chart .dashboard-large-chart-inner:first-child,.dashboard-medium-chart:first-child,.dashboard-small-chart .dashboard-small-chart-inner:first-child,.dashboard-tendency-container:first-child{margin-left:0}.dashboard-bar-chart-container,.dashboard-full-width-chart,.dashboard-large-chart,.dashboard-medium-chart,.dashboard-small-chart,.dashboard-tendency-container{margin-bottom:10px;position:relative}.dashboard-sub-bar-menu{cursor:pointer;position:absolute;right:9px;top:6px}.dataNotReadyYet{font-family:'Open Sans',sans-serif;font-size:20px;font-weight:100;text-align:center}.dashboard-sub-bar{background-color:#686766;color:#fff;height:24px;line-height:24px;margin:0;padding:0 6px}.dashboard-full-width-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-subtitle-bar.top{border-bottom:1px solid #e1e1e1;height:48px;line-height:48px;text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{border-left:1px solid #e1e1e1}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner{margin-left:10px;margin-right:10px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table{margin-bottom:10px;margin-top:10px;table-layout:fixed;width:100%}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-medium-chart .dashboard-interior-chart{margin-bottom:0}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table .no-data{font-style:italic;font-weight:100}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table tr{border-bottom:1px solid rgba(0,0,0,.025)}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:first-child{width:100px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:last-child{text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart:first-child{border-left:0}.dashboard-full-width-chart .state{background-color:#fff;border-radius:5px;color:#000;margin-left:5px;padding-left:6px;padding-right:4px}.dashboard-large-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-large-chart .dashboard-large-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-small-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-small-chart .dashboard-small-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:5px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart-outer:first-child{margin-right:10px}.dashboard-medium-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;margin-bottom:0;padding-top:10px}.dashboard-medium-chart:first-child{margin-right:12px}.dashboard-medium-chart .dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart .dashboard-medium-chart-menu{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:0 solid rgba(0,0,0,.3);color:rgba(0,0,0,.3);cursor:pointer;padding:0 4px;position:absolute;z-index:1000}.dashboard-medium-chart .dashboard-medium-chart-menu:hover{color:rgba(0,0,0,.7)}.dashboard-medium-chart .dashboard-medium-chart-inner{padding-bottom:10px}.dashboard-medium-chart .clusterChart .slice path{fill-opacity:.15;stroke-opacity:1;stroke-width:1.5px}.dashboard-tendency-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-tendency-container .dashboard-tendency-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{background-color:#fff;margin-top:5px;padding:0 8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency:first-child{border-right:1px solid #e1e1e1}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar{border-bottom:1px solid #e1e1e1;text-align:right}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure{text-align:center}.dashboard-bar-chart-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-bar-chart-container .dashboard-bar-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{margin-top:5px;padding:0 8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{font-weight:400}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{text-align:right}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-legend .dashboard-legend-inner{padding:0 5px 5px 0}.dashboard-spacer{margin:0 12px}.headerBar.dashboard-headerbar{margin:20px 0}.modal-chart-detail .modal-dashboard-legend .dashboard-legend-inner{padding-left:20px}.dashboard-half-height-legend .dashboard-legend-inner{padding-top:20px}.dashboard-title-bar{background-color:#686766;color:#fff;font-size:14.5px;font-weight:400;height:30px;line-height:30px;padding:0 5px 0 10px}.dashboard-title-bar .dashboard-half-title-bar{border-left:1px solid #000;margin-left:-1px;width:50%}.dashboard-title-bar .dashboard-half-title-bar:first-child{border-left:0;margin-left:0}.dashboard-row{margin-bottom:0;margin-left:0;margin-right:0}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{color:#666}.resizecontainer{margin:0 auto}@media (max-width:738px){#arangoCollectionUl{display:none}#collectionsDropdown ul{width:auto!important}#arangoCollectionSelect{display:inline-block;height:29px;margin-top:1px}}@media (min-width:739px) and (max-width:1041px){#arangoCollectionUl a{font-size:12px;height:12px;padding:8px 5px}}@media (min-width:1042px) and (max-width:1284px){#arangoCollectionUl a{font-size:14px}}@media (min-width:250px) and (max-width:489px){.resizecontainer{width:228px}.dashboard-full-width-chart{width:225px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:215px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:69.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:214px}.dashboard-large-chart{width:146px}.dashboard-large-chart .dashboard-sub-bar{width:134px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:136px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:106px}.dashboard-medium-chart{width:96px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:95px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:96px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:79px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:66px}.dashboard-small-chart .dashboard-sub-bar{width:54px}.dashboard-small-chart .dashboard-small-chart-inner{width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:54px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:56px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:40px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-114px;width:248px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:208px}.modal-body .dashboard-large-chart{width:143px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:131px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:133px}.modal-body .dashboard-medium-chart-outer{float:left;width:91px}.modal-body .dashboard-medium-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:89px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:74px}.modal-body .dashboard-small-chart{width:61px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:49px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:51px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:6.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:51px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:56px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:40px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:228px}.application-detail-view aside.meta{display:none}}@media (min-width:490px) and (max-width:729px){.resizecontainer{width:468px}.dashboard-full-width-chart{width:465px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:455px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:149.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart{width:306px}.dashboard-large-chart .dashboard-sub-bar{width:294px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:296px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:226px}.dashboard-medium-chart{width:216px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:215px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:216px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:199px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:146px}.dashboard-small-chart .dashboard-sub-bar{width:134px}.dashboard-small-chart .dashboard-small-chart-inner{width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:48px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:134px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:136px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:120px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-234px;width:488px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:448px}.modal-body .dashboard-large-chart{width:303px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:291px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:293px}.modal-body .dashboard-medium-chart-outer{float:left;width:211px}.modal-body .dashboard-medium-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:194px}.modal-body .dashboard-small-chart{width:141px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:129px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:131px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:46.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:131px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:136px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:120px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:468px}.application-detail-view aside.meta{display:none}}@media (min-width:730px) and (max-width:969px){.resizecontainer{width:708px}.dashboard-full-width-chart{width:705px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:695px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:229.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:694px}.dashboard-large-chart{width:466px}.dashboard-large-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:456px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:346px}.dashboard-medium-chart{width:336px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:335px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:319px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:226px}.dashboard-small-chart .dashboard-sub-bar{width:214px}.dashboard-small-chart .dashboard-small-chart-inner{width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:88px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:214px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:216px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:200px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-354px;width:728px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:688px}.modal-body .dashboard-large-chart{width:463px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:451px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:453px}.modal-body .dashboard-medium-chart-outer{float:left;width:331px}.modal-body .dashboard-medium-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:329px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:314px}.modal-body .dashboard-small-chart{width:221px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:211px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:86.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:211px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:216px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:200px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:508px}}@media (min-width:970px) and (max-width:1209px){.resizecontainer{width:948px}.dashboard-full-width-chart{width:945px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:935px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:309.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart{width:626px}.dashboard-large-chart .dashboard-sub-bar{width:614px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:220px;width:496px}.dashboard-sub-bar-menu{font-size:13px}.dashboard-medium-chart-outer{float:left;width:466px}.dashboard-medium-chart{width:456px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:455px}.dashboard-medium-chart .dashboard-interior-chart{height:220px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:13px;left:438px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:220px;width:456px}.dashboard-medium-chart #clusterGraphs svg text{font-size:11px}.dashboard-small-chart{width:306px}.dashboard-small-chart .dashboard-sub-bar{width:294px}.dashboard-small-chart .dashboard-small-chart-inner{width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:229px;width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:11px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:96.5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:128px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:31.17px;line-height:31.17px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:52.33px;line-height:25.17px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:294px}.dashboard-bar-chart-container{height:98px}.dashboard-bar-chart-container .dashboard-bar-chart{height:96px;width:296px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:31.33px;line-height:31.33px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:45.67px;line-height:45.67px;padding:5px 8px 10px;width:280px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:50.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-474px;width:968px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:13px;min-height:225px;width:130px}.absolut,.percentage{font-size:15px}.modal-chart-detail .modal-inner-detail{width:808px}.modal-body .dashboard-large-chart{width:623px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:611px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:493px}.modal-body .dashboard-medium-chart-outer{float:left;width:451px}.modal-body .dashboard-medium-chart{width:451px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:433px}.modal-body .dashboard-small-chart{width:301px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:289px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:291px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:126.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:291px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:296px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:280px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:11px;font-weight:400}.dashboard-subtitle-bar{font-size:15px;font-weight:300}.dashboard-figure{font-size:18px;font-weight:400}.dashboard-figurePer{font-size:16px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:11px}.dashboard-legend{height:225px;margin-top:-3px;width:120px}.dashboard-half-height-legend{font-size:11px;height:117.5px;width:60px}.application-detail-view section.info{width:748px}}@media (min-width:1210px) and (max-width:1449px){.resizecontainer{width:1188px}.dashboard-full-width-chart{width:1185px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1175px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:389.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1174px}.dashboard-large-chart{width:786px}.dashboard-large-chart .dashboard-sub-bar{width:774px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:255px;width:646px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:586px}.dashboard-medium-chart{width:576px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:575px}.dashboard-medium-chart .dashboard-interior-chart{height:255px;width:446px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:16px;left:555px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:255px;width:576px}.dashboard-medium-chart #clusterGraphs svg text{font-size:12px}.dashboard-small-chart{width:386px}.dashboard-small-chart .dashboard-sub-bar{width:374px}.dashboard-small-chart .dashboard-small-chart-inner{width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:264px;width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:114px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:168px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:37px;line-height:37px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:64px;line-height:31px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:374px}.dashboard-bar-chart-container{height:115.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:113.5px;width:376px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:37.17px;line-height:37.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:57.33px;line-height:57.33px;padding:5px 8px 10px;width:360px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:62.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-594px;width:1208px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:14px;min-height:260px;width:140px}.absolut,.percentage{font-size:18px}.modal-chart-detail .modal-inner-detail{width:1038px}.modal-body .dashboard-large-chart{width:783px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:771px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:643px}.modal-body .dashboard-medium-chart-outer{float:left;width:571px}.modal-body .dashboard-medium-chart{width:571px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:569px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:441px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:550px}.modal-body .dashboard-small-chart{width:381px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:369px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:371px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:166.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:371px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:376px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:360px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:18px;font-weight:300}.dashboard-figure{font-size:22px;font-weight:400}.dashboard-figurePer{font-size:20px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:13px;font-weight:400}.dashboard-legend{font-size:12px;font-weight:400;height:260px;margin-top:-3px;width:130px}.dashboard-half-height-legend{font-size:12px;height:135px;width:65px}.application-detail-view section.info{width:988px}}@media (min-width:1450px) and (max-width:1689px){.resizecontainer{width:1428px}.dashboard-full-width-chart{width:1425px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1415px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:469.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart{width:946px}.dashboard-large-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:796px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:706px}.dashboard-medium-chart{width:696px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:695px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:556px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:18px;left:673px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:696px}.dashboard-medium-chart #clusterGraphs svg text{font-size:13px}.dashboard-small-chart{width:466px}.dashboard-small-chart .dashboard-sub-bar{width:454px}.dashboard-small-chart .dashboard-small-chart-inner{width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:208px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:454px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:456px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:440px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-714px;width:1448px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:15px;min-height:290px;width:150px}.absolut,.percentage{font-size:20px}.modal-chart-detail .modal-inner-detail{width:1268px}.modal-body .dashboard-large-chart{width:943px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:931px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:793px}.modal-body .dashboard-medium-chart-outer{float:left;width:691px}.modal-body .dashboard-medium-chart{width:691px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:551px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:668px}.modal-body .dashboard-small-chart{width:461px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:451px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:206.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:451px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:456px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:440px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:20px;font-weight:300}.dashboard-figure{font-size:26px;font-weight:400}.dashboard-figurePer{font-size:24px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:13px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:13px;height:150px;width:70px}.application-detail-view section.info{width:1228px}}@media (min-width:1690px) and (max-width:1929px){.resizecontainer{width:1668px}.dashboard-full-width-chart{width:1665px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1655px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:549.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1654px}.dashboard-large-chart{width:1106px}.dashboard-large-chart .dashboard-sub-bar{width:1094px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:325px;width:936px}.dashboard-sub-bar-menu{font-size:16px}.dashboard-medium-chart-outer{float:left;width:826px}.dashboard-medium-chart{width:816px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:815px}.dashboard-medium-chart .dashboard-interior-chart{height:325px;width:656px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:22px;left:789px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:325px;width:816px}.dashboard-medium-chart #clusterGraphs svg text{font-size:14px}.dashboard-small-chart{width:546px}.dashboard-small-chart .dashboard-sub-bar{width:534px}.dashboard-small-chart .dashboard-small-chart-inner{width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:334px;width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:149px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:248px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:48.67px;line-height:48.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:87.33px;line-height:42.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:534px}.dashboard-bar-chart-container{height:150.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:148.5px;width:536px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:48.83px;line-height:48.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:80.67px;line-height:80.67px;padding:5px 8px 10px;width:520px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:85.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-834px;width:1688px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:16px;min-height:330px;width:170px}.absolut,.percentage{font-size:24px}.modal-chart-detail .modal-inner-detail{width:1488px}.modal-body .dashboard-large-chart{width:1103px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1091px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:933px}.modal-body .dashboard-medium-chart-outer{float:left;width:811px}.modal-body .dashboard-medium-chart{width:811px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:809px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:651px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:784px}.modal-body .dashboard-small-chart{width:541px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:529px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:531px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:246.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:531px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:536px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:520px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:14px;font-weight:400}.dashboard-subtitle-bar{font-size:24px;font-weight:300}.dashboard-figure{font-size:30px;font-weight:400}.dashboard-figurePer{font-size:28px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:14px}.dashboard-legend{height:330px;margin-top:-3px;width:160px}.dashboard-half-height-legend{font-size:14px;height:170px;width:80px}.application-detail-view section.info{width:1468px}}@media (min-width:1930px) and (max-width:2169px){.resizecontainer{width:1908px}.dashboard-full-width-chart{width:1905px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1895px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:629.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1894px}.dashboard-large-chart{width:1266px}.dashboard-large-chart .dashboard-sub-bar{width:1254px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:385px;width:1086px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:946px}.dashboard-medium-chart{width:936px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:935px}.dashboard-medium-chart .dashboard-interior-chart{height:385px;width:766px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:26px;left:905px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:385px;width:936px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:626px}.dashboard-small-chart .dashboard-sub-bar{width:614px}.dashboard-small-chart .dashboard-small-chart-inner{width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:394px;width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:179px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:288px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:58.67px;line-height:58.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:107.33px;line-height:52.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:614px}.dashboard-bar-chart-container{height:180.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:178.5px;width:616px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:58.83px;line-height:58.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:100.67px;line-height:100.67px;padding:5px 8px 10px;width:600px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:105.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-954px;width:1928px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:390px;width:180px}.absolut,.percentage{font-size:28px}.modal-chart-detail .modal-inner-detail{width:1718px}.modal-body .dashboard-large-chart{width:1263px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1251px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1083px}.modal-body .dashboard-medium-chart-outer{float:left;width:931px}.modal-body .dashboard-medium-chart{width:931px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:929px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:761px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:900px}.modal-body .dashboard-small-chart{width:621px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:609px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:611px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:286.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:611px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:616px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:600px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:28px;font-weight:300}.dashboard-figure{font-size:34px;font-weight:400}.dashboard-figurePer{font-size:32px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:14px;font-weight:400}.dashboard-legend{font-size:15px;font-weight:400;height:390px;margin-top:-3px;width:170px}.dashboard-half-height-legend{font-size:15px;height:200px;width:85px}.application-detail-view section.info{width:1708px}}@media (min-width:2170px) and (max-width:2409px){.resizecontainer{width:2148px}.dashboard-full-width-chart{width:2145px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2135px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:709.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2134px}.dashboard-large-chart{width:1426px}.dashboard-large-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1276px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1066px}.dashboard-medium-chart{width:1056px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1055px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:916px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1031px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1056px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:706px}.dashboard-small-chart .dashboard-sub-bar{width:694px}.dashboard-small-chart .dashboard-small-chart-inner{width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:328px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:694px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:696px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:680px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1074px;width:2168px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:1988px}.modal-body .dashboard-large-chart{width:1423px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1411px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1273px}.modal-body .dashboard-medium-chart-outer{float:left;width:1051px}.modal-body .dashboard-medium-chart{width:1051px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1049px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:911px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1026px}.modal-body .dashboard-small-chart{width:701px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:691px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:326.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:691px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:696px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:680px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:1948px}}@media (min-width:2410px) and (max-width:2649px){.resizecontainer{width:2388px}.dashboard-full-width-chart{width:2385px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2375px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:789.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2374px}.dashboard-large-chart{width:1586px}.dashboard-large-chart .dashboard-sub-bar{width:1574px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1436px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1186px}.dashboard-medium-chart{width:1176px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1175px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1036px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1151px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1176px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:786px}.dashboard-small-chart .dashboard-sub-bar{width:774px}.dashboard-small-chart .dashboard-small-chart-inner{width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:368px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:774px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:776px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:760px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1194px;width:2408px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2228px}.modal-body .dashboard-large-chart{width:1583px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1571px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1433px}.modal-body .dashboard-medium-chart-outer{float:left;width:1171px}.modal-body .dashboard-medium-chart{width:1171px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1169px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1031px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1146px}.modal-body .dashboard-small-chart{width:781px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:769px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:771px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:366.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:771px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:776px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:760px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2188px}}@media (min-width:2650px) and (max-width:2889px){.resizecontainer{width:2628px}.dashboard-full-width-chart{width:2625px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2615px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:869.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2614px}.dashboard-large-chart{width:1746px}.dashboard-large-chart .dashboard-sub-bar{width:1734px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1596px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1306px}.dashboard-medium-chart{width:1296px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1295px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1156px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1271px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1296px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:866px}.dashboard-small-chart .dashboard-sub-bar{width:854px}.dashboard-small-chart .dashboard-small-chart-inner{width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:408px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:854px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:856px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:840px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1314px;width:2648px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2468px}.modal-body .dashboard-large-chart{width:1743px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1731px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1593px}.modal-body .dashboard-medium-chart-outer{float:left;width:1291px}.modal-body .dashboard-medium-chart{width:1291px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1289px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1151px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1266px}.modal-body .dashboard-small-chart{width:861px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:849px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:851px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:406.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:851px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:856px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:840px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2428px}}div.centralRow{margin-bottom:40px;margin-top:40px}div.centralContent{background-color:transparent;height:100%;margin-left:-5px;margin-right:-5px;min-height:80px;padding:5px;width:100%}.contentDiv{list-style:none;padding:13px 0 0}.contentDiv li{background-color:rgba(0,0,0,.05)}.contentDiv a.add{display:block;font-weight:400;padding:40px 0;text-align:left}.contentDiv .icon{padding-left:5px;padding-right:5px;padding-top:10px}.contentDiv:after{clear:both}.contentDiv:after,.contentDiv:before{content:'';display:table;line-height:0}body{background-color:rgba(245,248,240,.95)}.headerButtonBar select{border:1px solid rgba(140,138,137,.25);height:28px} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome/fontawesome-webfont.eot?v=4.4.0);src:url(../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.4.0) format("embedded-opentype"),url(../fonts/fontawesome/fontawesome-webfont.woff2?v=4.4.0) format("woff2"),url(../fonts/fontawesome/fontawesome-webfont.woff?v=4.4.0) format("woff"),url(../fonts/fontawesome/fontawesome-webfont.ttf?v=4.4.0) format("truetype"),url(../fonts/fontawesome/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.modal-body,button{font-family:'Open Sans',sans-serif!important}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa.fa-pull-right,.fa.pull-right{margin-left:.3em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right,.pull-right{float:right}.contentDiv li,.dashboard-bar-chart-container,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage,.dashboard-full-width-chart,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart,.dashboard-half-height-legend,.dashboard-large-chart,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-legend,.dashboard-medium-chart,.dashboard-medium-chart .dashboard-interior-chart,.dashboard-small-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart,.dashboard-sub-bar,.dashboard-sub-bar .dashboard-sub-bar-title,.dashboard-tendency-container,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar,.dashboard-title-bar .dashboard-half-title-bar,.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.machineClass,.modal-chart-detail,.modal-chart-detail .modal-body,.modal-chart-detail .modal-dashboard-legend,.modal-chart-detail .modal-inner-detail,.navlist li,.navlogo,.pull-left,.scenarioMachine,.script-dropdown-menu,.user-dropdown-menu,a.button-gui,a.headerButton,div .bigtile,div .bigtile a span.add-Icon,div .tile,div .tile a span.add-Icon,div.centralContent,div.dropdownInner ul,div.footer-center,div.footer-left,div.footer-left p{float:left}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.dashboard-sub-bar-menu,.headerBar>div.headerButtonBar,.navmenu,.search-field,div .bigtile .iconSet span,div .tile .iconSet span,div.footer-right,div.footer-right p,ul.headerButtonList li{float:right}.dashboard-bar-chart-container .dashboard-bar-chart:after,.dashboard-medium-chart .dashboard-medium-chart-inner:after,.dashboard-medium-chart .dashboard-medium-chart-menu:after,.dashboard-row:after,.dashboard-sub-bar:after,.dashboard-tendency-container .dashboard-tendency-chart:after,.detail-chart:after,.headerBar>div.headerButtonBar:after,.machineClass:after,.resizecontainer:after,.scenarioSingleMachine:after,.tileList:after{clear:both;content:'.';display:block;font-size:0;height:0;visibility:hidden}.addButton,.arangoicon,.clusterDownBtn button,.contentDiv .icon,.deleteButton,.gv-search-submit-icon,.icon-info-sign,.scenarioImage,.script-dropdown-menu .dropdown-item,.search-submit-icon,a.button-gui,a.headerButton,div .bigtile,div .bigtile .iconSet span,div .bigtile a span.icon,div .bigtile a svg,div .tile .iconSet span,div .tile a span.icon,div .tile a svg,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,div.toolbox div.gv_action_button{cursor:pointer}.navbar,footer.footer{background-color:rgba(245,248,240,.95);color:#fff;left:0;position:fixed;right:0;width:100%;z-index:1000}.button-danger{background-color:#da4f49}.button-danger:focus,.button-danger:hover{background-color:#be342e}.deleteButton,a.danger.coordinator,a.danger.dbserver{color:#da4f49}.deleteButton:focus,.deleteButton:hover,a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{color:#be342e}a.danger.coordinator,a.danger.dbserver{fill:#da4f49}a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{fill:#be342e}.button-success{background-color:#8aa051}.button-success:focus,.button-success:hover{background-color:#788f3d}.addButton,a.success.coordinator,a.success.dbserver{color:#8aa051}.addButton:focus,.addButton:hover,a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{color:#788f3d}a.success.coordinator,a.success.dbserver{fill:#8aa051}a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{fill:#788f3d}.button-warning{background-color:#faa732}.button-warning:focus,.button-warning:hover{background-color:#f89406}a.warning.coordinator,a.warning.dbserver{color:#faa732;fill:#faa732}a.warning.coordinator:focus,a.warning.coordinator:hover,a.warning.dbserver:focus,a.warning.dbserver:hover{color:#f89406;fill:#f89406}.button-close,.button-neutral{background-color:#8f8d8c}.button-close:focus,.button-close:hover,.button-neutral:focus,.button-neutral:hover{background-color:#736b68}.dashboard-sub-bar-menu{color:#8f8d8c}.dashboard-sub-bar-menu:focus,.dashboard-sub-bar-menu:hover{color:#736b68}.button-primary{background-color:#564e4a}.button-primary:focus,.button-primary:hover{background-color:#3a322e}.button-header,a.button-gui,a.headerButton{background-color:#fff;border:1px solid #fff;color:#555}.button-header:focus,.button-header:hover,a.button-gui:focus,a.button-gui:hover,a.headerButton:focus,a.headerButton:hover{background-color:#8aa051;border:1px solid #8aa051;color:#fff}.button-notification{background-color:#faa020}.button-notification:focus,.button-notification:hover{background-color:#f87c0f}.button-inactive,.button-inactive:focus,.button-inactive:hover,[class*=' button-']:disabled,[class*=' button-']:focus:disabled,[class*=' button-']:hover:disabled,[class^=button-]:disabled,[class^=button-]:focus:disabled,[class^=button-]:hover:disabled,button.disabled,button.disabled:focus,button.disabled:hover{background-color:#d3d3d3}a.headerButton.disabled,a.headerButton.disabled:focus,a.headerButton.disabled:hover,a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{color:#d3d3d3}a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{fill:#d3d3d3}div.queryline .fa.fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:relative;right:21px;top:-1px}div.queryline .fa.fa-search:hover{cursor:pointer;opacity:1}.modal-body .select2-choices input,.modal-body input,.modal-body select,.modal-body textarea,.navbar .arango-collection-select,div.queryline input,div.queryline select,input.search-input{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#fff!important;border:1px solid rgba(140,138,137,.25);box-shadow:none;outline:transparent 0}.modal-body input:focus,.modal-body select:focus,.modal-body textarea:focus,.navbar .arango-collection-select:focus,div.queryline input:focus,div.queryline select:focus,input.search-input:focus{border-color:#999;box-shadow:none;outline:transparent 0}.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.script-dropdown-menu,.user-dropdown-menu{background-color:#f5f8f0;border-color:#666;border-radius:3px;border-style:solid;border-width:1px;box-shadow:none;display:none;list-style:none;margin:5px 0 0;padding:5px 0;position:absolute;right:0;top:80%;z-index:1000}.script-dropdown-menu .dropdown-item a,.tab{display:block}.dropdown-toolbar li,.gv-dropdown-menu li,.link-dropdown-menu li,.script-dropdown-menu li,.user-dropdown-menu li{line-height:23px;white-space:nowrap;width:100%}.dropdown-toolbar .dropdown-header,.gv-dropdown-menu .dropdown-header,.link-dropdown-menu .dropdown-header,.script-dropdown-menu .dropdown-header,.user-dropdown-menu .dropdown-header{color:#999;font-size:15px;font-weight:600;font-variant:small-caps;padding:0}.dropdown-toolbar .dropdown-header:hover,.gv-dropdown-menu .dropdown-header:hover,.link-dropdown-menu .dropdown-header:hover,.script-dropdown-menu .dropdown-header:hover,.user-dropdown-menu .dropdown-header:hover{cursor:default}.dropdown-toolbar .divider,.gv-dropdown-menu .divider,.link-dropdown-menu .divider,.script-dropdown-menu .divider,.user-dropdown-menu .divider{background-color:#666;height:1px;margin:10px 0 5px}.dropdown-toolbar a,.gv-dropdown-menu a,.link-dropdown-menu a,.script-dropdown-menu a,.user-dropdown-menu a{color:#fff;padding:0 20px}.navbar{-webkit-font-smoothing:subpixel-antialiased;height:44px;margin-bottom:3px;padding-top:6px;top:0}.navbar .no-left-margin{border:0;margin-left:0}.navbar .no-left-margin.hover{background-color:transparent}.navbar .arangodbLogo{height:auto;margin-left:-5px;margin-top:-1px;width:40%}.navbar .arango-collection-select{position:relative;right:-22px;top:4px}.navbar .nav .dropdown .active>.dropdown-toggle,.navbar .nav .dropdown .open.active>.dropdown-toggle,.navbar .nav .dropdown .open>.dropdown-toggle{background:#788f3d}.navbar .nav>.active>a{-webkit-box-shadow:0 0 0 transparent inset;-moz-box-shadow:0 0 0 transparent inset;box-shadow:0 0 0 transparent inset;background-color:#fff;color:#000}.navbar .nav>li>a:focus{background-color:#fff}.navbar .nav>li>a:hover{background-color:#000;color:#686766}.navlist .dropdown-item:hover a,.navlist>.active a,.navlist>.active:hover a,.navlist>li:hover a{color:#000}.navlogo{margin-left:5px;margin-right:-3px;padding-top:3px}.navlist{list-style:none}.navlist>li{height:39px}.navlist li{border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;margin-left:7px}.navlist li.dropdown:hover{background-color:#fff;border-bottom-left-radius:0;border-bottom-right-radius:0;border-left:1px solid rgba(0,0,0,.2);border-right:1px solid rgba(0,0,0,.2);border-top:1px solid rgba(0,0,0,.2)}.navlist li.dropdown:hover a{border-bottom:2px solid #fff}.navlist li.divider,.navlist li.navbar-spacer{border:0}.navlist li.divider{background-color:rgba(0,0,0,.2)}.navlist li.navbar-spacer{background-color:#a0a0a0;height:21px;margin-top:9px;width:1px}.navlist li.navbar-spacer.big{margin-left:15px;margin-right:15px}.navlist li.navbar-spacer.med{margin-left:5px;margin-right:5px}.navlist .dropdown-item,.script-dropdown-menu .dropdown-item{margin-left:0}.navlist li.navbar-spacer:hover{background-color:#a0a0a0}.navlist .active .tab{border-bottom:2px solid #8aa051;padding-bottom:4px}.navlist>.active{background-color:transparent}.navlist>.active:hover{background-color:#fff}.navlist .dropdown-item:hover,.navlist>li:hover{background-color:#fff;border-radius:3px}.navlist .dropdown-item a{border-bottom:0;display:block;font-size:11pt}.navlist .dropdown-item a:hover{background-color:#dee9cf;color:#686766}.tab{color:#686766;font-size:12pt;font-weight:100;padding:9px 5px 10px}.tab.userImg{padding-bottom:5px}.dropdown-item a{border-bottom:0!important;font-weight:300}.dropdown-toolbar,div.headerBar,div.headerDropdown{border:1px solid rgba(140,138,137,.25)}.dropdown-toolbar li a,footer.footer p{font-weight:100}.dropdown-toolbar{background-color:#fff!important}.dropdown-toolbar li a:hover{background:0 0;background-color:#dee9cf!important;color:#000!important}.link-dropdown-menu,.user-dropdown-menu{background-color:#fff;border:1px solid rgba(0,0,0,.2);border-top-right-radius:0;margin-right:-1px;margin-top:7px;z-index:-10}.link-dropdown-menu .dropdown-item,.user-dropdown-menu .dropdown-item{border-left:0;border-right:0}.script-dropdown-menu .dropdown-item a:hover{color:#fff}.script-dropdown-menu .dropdown-item:hover{background-color:#8aa051}.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:rgba(0,0,0,.7);border:1px solid #c2c2c2;margin-right:-20px;margin-top:6px}.gv-dropdown-menu:after{border-bottom-color:#fff}.gv-dropdown-menu li:hover{background-color:#fff;background-image:none}.gv-dropdown-menu li a{padding:0}.gv-dropdown-menu li a label{color:#fff;padding-left:5px}.gv-dropdown-menu li a:focus{background-color:#8aa051!important;background-image:none}#arangoCollectionSelect{display:none;float:right;margin-bottom:0;margin-right:15px;padding-bottom:0}.caret{border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #686766;content:'';display:inline-block;height:0;vertical-align:top;width:0}.applications-menu{display:block}.arango-logo{height:34px;padding:0!important}.arango-logo img{margin-left:22px}.footer{bottom:0;font-size:14px;left:0;position:fixed;right:0;z-index:1000}.modal,.select2-drop-active{z-index:9999999}footer.footer{bottom:0;height:40px}footer.footer p{font-size:10pt;margin-bottom:0;padding-bottom:10px;padding-top:10px}div.footer-left{background:none;color:#686766;width:45%}div.footer-left .social-icons{margin-top:5px}div.footer-left .social-icons a{display:block;float:left;height:25px;width:25px}div.footer-left .social-icons p{background:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;height:25px;margin-right:10px;padding:0;width:25px}div.footer-left .social-icons p:hover{background:#8aa051;cursor:pointer}div.footer-left .social-icons p:hover i{color:#fff}div.footer-left .social-icons i{color:#000;margin-top:6px;position:absolute}.addButton,.deleteButton{position:relative;font-size:22px}div.footer-left .social-icons i.fa-twitter{margin-left:-5px}div.footer-left .social-icons i.fa-envelope{margin-left:-19px}div.footer-left .social-icons i.fa-google{margin-left:-17px;margin-top:7px}div.footer-left .social-icons i.fa-stack-overflow{margin-left:-17px}div.footer-center{background:none;color:#686766;width:10%}div.footer-center i{background-color:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;margin-left:1px;padding:6px 2px;width:20px}div.footer-center i:hover{background-color:#8aa051;color:#fff}div.footer-center p{padding-top:5px}div.footer-center p:hover{cursor:pointer}[class*=' button-']:disabled,[class^=button-]:disabled,a.headerButton.disabled,button.disabled{cursor:not-allowed}div.footer-right{background:none;color:#686766;width:45%}div.footer-right p{color:#fff}div.footer-right i{color:#da4f49;font-size:18px}div.footer-right a{color:#686766;margin-left:5px;position:relative;top:-1px}div.footer-right .isOnline{color:#8aa051!important}.button-close,.button-danger,.button-header,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;font-size:14px;font-weight:300!important}.button-close,.button-danger,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{border:0;color:#fff;margin-left:10px;padding:5px 16px}.button-header{margin-top:5px}.addButton{margin-right:7px;margin-top:2px}.deleteButton{padding-right:3px;top:3px}#closeBtnInfoView{margin-left:0!important}button.btn-server{width:120px}button.gv-zoom-btn{background-size:14px 14px;height:14px;vertical-align:baseline;width:14px}button.gv-zoom-btn.btn-zoom-right{border:0;box-shadow:none;right:0;top:13px}button.gv-zoom-btn.pan-right{background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-right:hover{background:inherit;background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-left{background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-left:hover{background:inherit;background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-top{background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-top:hover{background:inherit;background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-bottom{background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.pan-bottom:hover{background:inherit;background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.btn-zoom{height:14px;margin:0;padding:0;position:absolute;width:16px}button.gv-zoom-btn.btn-zoom-top{border:0;box-shadow:none;left:13px;top:1}button.gv-zoom-btn.btn-zoom-left{border:0;box-shadow:none;left:0;top:13px}button.gv-zoom-btn.btn-zoom-bottom{border:0;box-shadow:none;left:13px;top:25px}button.gv-icon-btn{-moz-border-radius:0!important;-webkit-border-radius:0!important;border-radius:0!important;background-size:36px 36px;height:36px;width:36px}button.gv-icon-btn.active{background-color:#8aa051}button.gv_dropdown_entry{height:30px;margin:4px 4px 4px 30px;width:160px}button.gv_context_button{width:65px}button.large-distance{margin-left:12px}button.short-distance{margin-left:6px}button.shutdown{margin-top:6px;padding:3px 14px}button.graphViewer-icon-button{background-color:transparent;border:0;height:20px;margin-left:5px;margin-top:-2px;padding:0;width:20px}button.graphViewer-icon-button img{height:20px;padding-bottom:10px;width:20px}ul.headerButtonList{display:inline-block;margin-bottom:0;margin-left:0;padding-left:0!important}ul.headerButtonList li{display:inline}a.button-gui,a.headerButton{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;margin-left:5px;margin-right:5px}a.headerButton{margin-top:2px;position:relative}a.headerButton .fa,a.headerButton [class*=" icon_"],a.headerButton [class^=icon_]{display:block;height:23px;line-height:23px;position:static;right:0;text-align:center;top:0;width:27px}a.button-gui.button-gui-disabled,div.headerDropdown,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox{display:none}a.headerButton .icon_arangodb_arrowleft,a.headerButton .icon_arangodb_arrowright{font-weight:700}a.headerButton.activated{background-color:#788f3d;border:1px solid #788f3d;color:#fff}div.toolbox,div.toolbox div.gv_action_button{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#fff}a.headerButton.activated:hover{background-color:#fff;color:#788f3d}div.toolbox{border-radius:3px;border:1px solid rgba(140,138,137,.25);margin-right:5px;margin-top:-3px;padding-bottom:5px;padding-top:5px;position:absolute}div.toolbox div.gv_action_button{border-radius:3px;color:#555;height:30px;margin:5px;position:relative;width:30px}div.toolbox div.gv_action_button.active{background-color:#8aa051;color:#fff}div.toolbox div.gv_action_button:first-child{margin-top:0}div.toolbox div.gv_action_button:last-child{margin-bottom:0}h6.gv_button_title,h6.gv_icon_icon{left:0;margin:0;position:absolute;right:0}h6.gv_icon_icon{font-size:22px;left:1px;top:4px}h6.gv_button_title{bottom:1px;display:none}.btn-icon{background-color:#383434;padding:4px}.gv-icon-small{background-size:16px 16px;height:16px!important;width:16px!important}.gv-icon-small.delete{background-image:url(../img/icon_delete.png)}.gv-icon-small.add{background-image:url(../img/plus_icon.png)}a.pagination-button,ul.arango-pagination a{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.badge,.btn,.label{text-shadow:none!important}.navbar-inner,.thumbnail{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0}.modal-body th.actionCell>button{margin-top:-12px}.btn-old-padding{padding-bottom:4px!important;padding-top:4px!important}button.btn-overview,button.btn-server{margin:5px}a.button-gui{height:auto;margin-bottom:0;margin-top:0;padding-bottom:1px;padding-top:1px;position:absolute;right:2px;text-decoration:none!important;top:2px;width:auto}.clusterDownBtn{padding-bottom:10px;padding-top:10px}.clusterDownBtn button{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#f1f1f1;border:1px solid rgba(0,0,0,.1875);color:#333;font-size:20px;font-weight:300;margin:0;padding:12px 18px;text-decoration:none!important;width:250px}.clusterDownBtn button:hover{background-color:#e8e8e8;color:#4a6c30;-webkit-transition-delay:0;-webkit-transition-duration:.2s;-webkit-transition-property:all;-webkit-transition-timing-function:ease-in}.clusterDownBtn button.green{background-color:#617e2b;color:#fff}.clusterDownBtn button.green:hover{background-color:#8ba142}.bottomButtonBar{background-color:#fff;border-top:1px solid rgba(104,103,102,.1);height:30px;padding:10px}.clusterInfoIcon{float:left;padding-left:5px;padding-top:2px}.waitModal.icon{font-size:100px;height:120px}.waitModal.message{font-size:20px}.icon_arangodb_info{color:#333;font-size:23px}li a [class*=" icon_arangodb"],li a [class^=icon_arangodb]{font-size:18px;position:absolute;right:4px;top:2px}.fa-minus-circle{color:#da4f49;font-size:14pt}.fa-minus-circle:hover{cursor:pointer}div.headerDropdown{background-color:#fff;border-radius:3px;clear:both;padding:10px;position:relative;width:auto}div.headerDropdown.smallDropdown .dropdownInner{min-height:20px}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.dropdown-title{margin-bottom:10px}div.dropdownInner{-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;min-height:125px;position:relative;width:auto}div.dropdownInner .nav-header{font-size:10pt}div.dropdownInner>.nav-header{color:#000;font-size:10pt;font-weight:400}div.dropdownInner>label{color:#000;font-weight:300}div.dropdownInner ul{border-left:1px solid rgba(140,138,137,.25);display:inline;list-style-type:none;margin-top:10px;min-height:105px;width:230px}div.dropdownInner ul:first-of-type,div.queryline input[type=file]{border:0}div.dropdownInner ul label{color:#000;padding-left:20px}div.dropdownInner ul li .fa{color:#999;margin-right:5px}div.dropdownInner ul li .fa.fa-square-o{margin-left:1px;margin-right:6px}div.dropdownInner ul li .fa.fa-check-circle-o,div.dropdownInner ul li .fa.fa-check-square-o,div.dropdownInner ul li .fa.fa-dot-circle-o{color:#8aa051}div.queryline{color:#000;height:35px}div.queryline .textDiv{margin-right:10px;margin-top:4px}div.queryline input,div.queryline select{margin-bottom:5px}div.queryline.querylineAdd span{color:#fff;padding-left:10px;position:relative;top:-21px}div.queryline .removeFilterItem i{margin-left:5px!important;margin-top:0!important}div.queryline div.searchByAttribute{margin-left:6px;margin-right:6px;position:relative}div.queryline div.searchByAttribute>ul.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:#fff;color:#fff;display:none;left:0;position:absolute;top:20px;width:247px}div.dropdownImport{background-color:#fff;border-radius:3px;display:none;position:relative;padding:10px 10px 5px}div.dropdownImport input{line-height:0;margin-bottom:-15px;margin-top:5px}select.filterSelect{color:#00f;margin-left:10px;margin-right:10px;width:100px}#filterHeader button{float:right;margin-left:10px!important;margin-top:1px}div.input-append button.gv_example_toggle{-moz-border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;background-color:#8f8d8c;height:30px;margin-left:-1px;padding-left:10px;padding-right:10px;padding-top:12px;vertical-align:top}div.input-append button.gv_example_toggle:hover{background-color:#8aa051}div.headerBar,div.headerBar .infoField{background-color:#fff;padding-left:5px;padding-right:5px}.searchEqualsLabel{margin-left:6px;margin-right:6px}img.gv-throbber{background-image:url(../img/swagger/throbber.gif)}span.gv_caret{border-top:5px solid #fff;margin-top:2px!important}input.search-input{height:14px;line-height:18px;margin-right:-1px;margin-top:6px;width:120px}.search-field{margin-left:10px}.search-field .fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:absolute;right:9px;top:9px}.search-field .fa-search:hover{cursor:pointer;opacity:1}.gv-search-submit-icon,.search-submit-icon{background-image:url(../img/enter_icon.png);background-size:14px;height:14px;margin-left:-18px;opacity:.2;position:absolute;width:14px}.gv-search-submit-icon:hover,.search-submit-icon:hover{opacity:.8}.search-submit-icon{margin-top:11px}.gv-search-submit-icon{margin-top:6px}div.headerBar{border-radius:3px;color:#fff;font-size:16px;height:36px;margin-bottom:5px;margin-top:15px;position:relative}div.headerBar .infoField{border:1px solid rgba(140,138,137,.25);border-radius:3px!important;color:#000;float:right;font-size:12px;margin-right:7px;margin-top:7px}div.headerBar .infoField .fa{cursor:pointer;margin-left:5px}div.headerBar input[type=checkbox].css-checkbox{display:none}div.headerBar input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;cursor:pointer;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerBar input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.headerBar input[type=radio]{display:none}div.headerBar input[type=radio] label span{background:url(../img/check_radio_sheet.png) -38px top no-repeat;cursor:pointer;display:inline-block;height:19px;margin:-1px 4px 0 0;vertical-align:middle;width:19px}#transparentHeader input[type=checkbox].css-checkbox,.lineGraph .many .dygraph-legend>span,.modal-delete-confirmation{display:none}div.headerBar input[type=radio]:checked+label span{background:url(../img/check_radio_sheet.png) -57px top no-repeat}.headerButtonList a.error{color:#da4f49}.headerButtonList a.error:hover{background-color:#da4f49;border-color:#da4f49;color:#fff}.headerBar a.arangoHeader{color:#000;font-size:13pt;font-weight:100;left:0;position:relative;top:7px}.headerBar>div.headerButtonBar{margin:4px 0;margin-bottom:0!important}.breadcrumb{background:0 0;border:0;border-radius:0;padding:7px 0}.breadcrumb .disabledBread{color:#666;float:left;font-size:13pt;font-weight:100;padding-right:5px;position:relative}.breadcrumb .disabledBread i{font-size:10pt;margin-left:10px}.breadcrumb .activeBread{color:#8aa051;float:left;font-size:13pt;font-weight:100}.arangoHeader{font-weight:400}.checkboxLabel{margin-top:4px;padding-left:0}.css-label{background-image:url(../img/dark-check-green.png)}.css-label-round{background-image:url(../img/dark-check-green-round.png)}.modal-dashboard-header,.modal-header{background-color:#fff;border-bottom:0!important;border-radius:3px;margin-top:5px;padding-left:5px;padding-right:10px;padding-top:4px}.modal-dashboard-header .arangoHeader,.modal-header .arangoHeader{color:#000;font-size:13pt;font-weight:100;left:5px;position:relative;top:2px}.modal-dashboard-header a,.modal-header a{top:2px!important}.modal-dashboard-header .close,.modal-header .close{color:#fff;font-weight:300;margin-top:2px;opacity:.5}.modal-dashboard-header .close:hover,.modal-header .close:hover{opacity:1}.modal-tabbar{border-bottom:1px solid #666}.modal-body{color:#736b68;font-size:14px;font-weight:300;max-height:410px}.modal-body .select2-choices{background-image:none!important;border:1px solid #999;border-radius:3px;-webkit-box-shadow:none;box-shadow:none}.modal-body .select2-choices input:active{-webkit-box-shadow:none;box-shadow:none;outline:0!important}.modal-body .select2-choices .select2-search-choice{margin:5px 0 3px 5px!important}.modal-body .select2-choices li{background-color:#fff!important;background-image:none!important;color:#000}.modal-body tr.first,.modal-body tr.last,.modal-body tr.middle{background-color:#f5f8f0}.modal-body .select2-choices li a{margin-left:1px;margin-top:-1px}.modal-body .select2-choices:active{border:1px solid #999;-webkit-box-shadow:none!important;box-shadow:none!important;outline:transparent!important}.modal-body .nav-tabs{margin-top:15px}.modal-body .nav-tabs>li>a:hover{border-color:#8c8a89}.modal-body input,.modal-body select,.modal-body textarea{margin-top:10px}.modal-body input[type=checkbox]{margin-bottom:10px}.modal-body input[type=text].invalid-input{border-color:rgba(234,23,23,.6)}.modal-body input[type=text].invalid-input:focus{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6)}.modal-body input[type=file]{line-height:17px}.modal-body tr.spacer{height:10px}.modal-body tr.first th:first-child{border-top-left-radius:3px}.modal-body tr.first th:last-child{border-top-right-radius:3px}.modal-body tr.middle{padding-left:10px;padding-right:10px}.modal-body tr.last th:first-child{border-bottom-left-radius:3px}.modal-body tr.last th:last-child{border-bottom-right-radius:3px}.modal-body tr.first th:first-child,.modal-body tr.last th:first-child,.modal-body tr.middle th:first-child{padding-left:10px}.modal-body tr.first th:last-child,.modal-body tr.last th:last-child,.modal-body tr.middle th:last-child{padding-right:10px}.modal-body th.actionCell{width:30px}.modal-body th.keyCell{width:170px}.modal-body th.keyCell input{width:150px}.modal-body th .valueCell{width:300px}.modal-body th .valueCell input{width:290px}.modal-body th .select2-container{margin-bottom:10px;margin-top:10px}.modal-body .icon-info-sign{margin-bottom:10px;margin-left:10px;opacity:.7;padding-bottom:5px}.modal-body .icon-info-sign:hover{opacity:1}.modal-body .icon_arangodb_info{color:#736b68;font-size:18px;margin-top:-10px;position:absolute;right:12px}.modal-body .icon_arangodb_info:hover{color:#000}.modal-body .collapse{margin-right:-14px;position:relative}.modal-body .accordion-inner{border-top:0;margin-left:0;padding-left:0;padding-right:0}.modal-body .accordion-toggle span .caret{border-top-color:#000;float:right;margin-top:5px}.modal-body .accordion-toggle.collapsed span .caret{-ms-transform:rotate(90deg);-webkit-transform:rotate(90deg);transform:rotate(90deg)}.modal-body input{width:384px}.modal-body select{width:398px}.modal-body .collectionTh{height:50px}.modal-body .tab-content{min-height:200px}.modal-body .tab-content .tab-pane{border-top:1px solid #666!important;margin-left:0!important;padding-top:10px}.modal-body .tab-content .tab-pane-modal{border-top:none!important}.modal-body .tab-content #appstore{max-height:290px}.modal-body .errorMessage{background-color:#fff;color:#da4f49;font-size:9pt;font-weight:400;margin-bottom:5px;margin-top:-9px;position:absolute}.modal-body .nav .tab-icon{margin-right:5px;margin-top:-3px;width:20px}.modal-text{font-weight:300;padding-bottom:3px;padding-top:3px}.modal-backdrop,.modal-backdrop.fade.in{opacity:.4}.modal{border:0!important;border-radius:3px!important;box-shadow:0;width:580px}.modal .fade.in{top:12.1%!important}.modal table tr:last-child{border-bottom:0!important}.waitModal{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:0 0;border:0;color:#fff}.waitModalBackdrop{opacity:.7!important}.modalTooltips span{color:#736b68;font-size:20px}.modalTooltips span:hover{color:#000}.gv-object-view{text-align:left;white-space:pre}.capitalize{text-transform:capitalize}.modal-footer{border-top:0!important;padding-right:17px}.modal-header{margin-left:5px;margin-right:5px}.modal-dashboard-header{margin-left:0;margin-right:0;padding-bottom:9px}.modal table tr,.thBorderBottom{border-bottom:1px solid #f7f3f2!important}.modal-delete-confirmation button{margin-right:10px;margin-top:-4px}.modal-delete-confirmation button .modal-confirm-delete{margin-right:-18px}.modal-delete-confirmation fieldset input{float:left}.modal-delete-confirmation fieldset label{float:left;margin-left:10px}.createModalDialog table{width:100%}.createModalDialog .collection-info-figures table{float:left;margin-left:0;margin-right:0;margin-top:0;min-width:200px;padding:3px;text-align:left}.createModalDialog .figures1,.createModalDialog .figures2{margin-bottom:20px;width:255px}.createModalDialog .figures2{margin-left:20px!important}.createModalDialog .figures3{margin-bottom:0;width:100%}.foxx-store-row .foxx-name{font-weight:700}.foxx-store-row .foxx-author{font-size:10pt;font-weight:300;margin-top:-4px}.foxx-store-row .foxx-version{font-weight:400}#new-app-mount{margin-right:24px;width:360px}#control_event_edge_delete_modal,#control_event_edge_edit_modal,#control_event_new_node_modal,#control_event_node_delete_modal,#control_event_node_edit_modal{margin-left:-320px;width:640px}.scenarioImage{height:70%;width:auto}svg.clusterChart{height:auto;margin:auto;width:auto}.lineGraph{position:absolute}.lineGraph .few .dygraph-legend>span.highlight{border:1px solid grey}.lineGraph .many .dygraph-legend>span.highlight{display:inline}a.coordinator,a.dbserver{color:#000;height:50px;position:absolute;top:10px;width:50px}a.coordinator h6.serverName,a.dbserver h6.serverName{bottom:0;font-size:11px;left:0;margin:0;position:absolute;right:0}a.coordinator.single{left:90px}a.coordinator.double{left:60px}a.dbserver.single{right:90px}a.dbserver.double{right:60px}.cluster-connection-check-success{color:#8aa051;margin-left:20px}.cluster-connection-check-fail{color:#da4f49;margin-left:20px}.cluster-unreachable-info{margin:0 auto;max-width:320px;padding-top:17px;text-align:center}.machineClass{background-color:#e1e1e1;margin-left:31px;margin-right:31px;padding:10px}.scenarioBox{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:rgba(0,0,0,.075);border:1px solid rgba(0,0,0,.19);height:65px;left:10px;margin-top:30px;position:absolute;right:10px;width:auto}.scenarioMachine,div .bigtile,div .tile{background-color:#fff;position:relative}.scenarioBox.bottomBox{bottom:30px}.scenarioBoxHeader{border-bottom:1px solid rgba(0,0,0,.19);height:18px;line-height:18px;margin-top:0;padding-bottom:0;text-align:center;width:auto}.scenarioBoxText{font-size:13px;font-weight:400;margin-top:17px;text-align:center;width:auto}.collectionName,div .bigtile .badge-success,div .tile .badge-success{font-weight:300}.scenarioMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;border:1px solid rgba(0,0,0,.19);height:257px;margin-right:17px;width:109px}.scenarioMachine:last-child{margin-right:0}.scenarioSingleMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background-color:#fff;border:1px solid rgba(0,0,0,.19)}.scenarioSingleMachine .scenarioMachine{border:1px solid transparent;height:238px}.bigtile.informationtile{cursor:auto}.informationText{background:#fff;font-size:12px;margin:10px;padding:5px;text-align:left}.tileList{margin-left:-6px;margin-right:-6px}.tileList legend{padding-left:5px}.tileList .tile:first-child a{opacity:.8}.tileList .tile:first-child a:hover{opacity:1}div .bigtile,div .tile{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border:1px solid #f5f8f0;border-radius:3px;font-size:14px;list-style:none;margin-bottom:13px;margin-left:6px;margin-right:6px;text-align:center;z-index:1}div .bigtile progress[value],div .tile progress[value]{color:#5bc0de}div .bigtile progress::-webkit-progress-bar-value,div .tile progress::-webkit-progress-bar-value{background:#5bc0de}div .bigtile progress::-webkit-progress-value,div .tile progress::-webkit-progress-value{background:#5bc0de}div .bigtile progress::-moz-progress-bar,div .tile progress::-moz-progress-bar{background:#5bc0de}div .bigtile progress,div .tile progress{-webkit-appearance:none;border-radius:0;height:2px;margin-top:16px;position:relative;width:100%;z-index:10}div .bigtile:hover,div .tile:hover{cursor:pointer}div .locked.bigtile,div .locked.tile{cursor:not-allowed;opacity:.5}div .locked.bigtile .iconSet span:hover,div .locked.tile .iconSet span:hover{background-color:#fff!important;color:#000;cursor:not-allowed!important}div .locked.bigtile .iconSet:hover,div .locked.tile .iconSet:hover{cursor:not-allowed!important}div .bigtile .collection-type-icon:hover,div .bigtile img:hover,div .tile .collection-type-icon:hover,div .tile img:hover{cursor:pointer}div .bigtile .warning-icons,div .tile .warning-icons{background-color:#da4f49;border-radius:3px;color:#fff;font-size:11px;height:17px;left:0;line-height:13px;margin-left:5px;margin-top:5px;padding-left:9px;padding-right:9px;position:absolute;top:0}div .bigtile a svg.icon,div .bigtile img.icon,div .tile a svg.icon,div .tile img.icon{height:50px;width:50px}div .bigtile .warning-icons .fa,div .tile .warning-icons .fa{font-size:11pt;margin-left:1px}div .bigtile .collection-type-icon,div .tile .collection-type-icon{color:#666;font-size:30pt;margin-top:12pt}div .bigtile img,div .tile img{position:relative}div .bigtile a span.add-Icon,div .tile a span.add-Icon{font-size:22px;margin-left:22px;margin-right:10px;margin-top:-5px;position:relative;right:4px;top:2px}div .bigtile a span.icon,div .tile a span.icon{font-size:50px}div .bigtile .tile-icon-svg,div .tile .tile-icon-svg{cursor:pointer;fill:#686766;height:50px;margin-left:90px;margin-top:10px;position:absolute;width:50px}div .bigtile .tile-icon,div .tile .tile-icon{color:#686766;font-size:50px;line-height:1.2}div .bigtile .icon_arangodb_edge5-2,div .tile .icon_arangodb_edge5-2{display:inline-block;position:relative;top:15px;-moz-transform:rotate(80deg);-o-transform:rotate(80deg);-webkit-transform:rotate(80deg)}div .bigtile h5,div .tile h5{background:#8c8a89;color:#fff;font-size:12px;margin:0;overflow:hidden!important;padding:4px 8px;text-overflow:ellipsis!important;white-space:nowrap!important}div .bigtile h5.inProgress,div .tile h5.inProgress{color:#5bc0de}div .bigtile .tileSelects,div .tile .tileSelects{margin-left:40px;position:relative;z-index:9999}div .bigtile .tileSelects select,div .tile .tileSelects select{float:right;height:20px;margin-right:5px;margin-top:16px;width:70px}div .bigtile .fullBorderBox,div .tile .fullBorderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:100%;position:absolute;width:100%}div .bigtile .borderBox,div .tile .borderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:75px;position:absolute;width:224px}.collectionName,.dashboard-sub-bar{border-bottom-left-radius:3px;border-bottom-right-radius:3px}div .bigtile .iconSet,div .tile .iconSet{position:absolute;right:5px;top:5px}div .bigtile .iconSet span,div .tile .iconSet span{border-radius:3px;color:#666;font-size:18px;z-index:2;padding:2px 3px}div .bigtile .iconSet span:hover,div .tile .iconSet span:hover{background-color:#8aa051;color:#fff}div .bigtile .iconSet span.disabled,div .tile .iconSet span.disabled{cursor:default;opacity:.2}div .bigtile .iconSet span.disabled:hover,div .tile .iconSet span.disabled:hover{background-color:#fff;color:#000;cursor:default;opacity:.2}div .bigtile .unloaded div,div .tile .unloaded div{border-bottom:16px solid #ff8f35}div .bigtile .deleted div,div .tile .deleted div{border-bottom:16px solid #700}div .bigtile .tileBadge,div .tile .tileBadge{bottom:29px;font-size:11px;font-weight:300;position:absolute;right:0}div .bigtile .tileBadge button,div .tile .tileBadge button{margin-left:0;margin-right:5px}div .bigtile .tileBadge span,div .tile .tileBadge span{display:inline-block;line-height:15px}div .bigtile .tileBadge span .corneredBadge,div .tile .tileBadge span .corneredBadge{border-bottom-style:solid;border-bottom-width:17px;border-left:5px solid transparent;border-radius:3px;color:#fff;height:0;margin-bottom:4px;margin-right:5px;padding-left:1px;padding-right:6px}div .bigtile .tileBadge span .corneredBadge.loading,div .tile .tileBadge span .corneredBadge.loading{border-bottom-color:#ff8f35}div .bigtile .tileBadge span .corneredBadge.loaded,div .tile .tileBadge span .corneredBadge.loaded{border-bottom-color:#8aa051}div .bigtile .tileBadge span .corneredBadge.development,div .bigtile .tileBadge span .corneredBadge.unloaded,div .tile .tileBadge span .corneredBadge.development,div .tile .tileBadge span .corneredBadge.unloaded{border-bottom-color:#ff8f35}div .tile{height:100px;width:226px}div .tile-graph .tile-icon:hover{cursor:pointer}div .bigtile{height:309px;width:452px}div .bigtile .shardContainer{font-size:30px}div .bigtile .shardContainer span{padding:2px}.collectionName{bottom:0;left:0;position:absolute;right:0;text-align:left}.dashboard-bar-chart-container,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-medium-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-tendency-container{border-top-left-radius:3px;border-top-right-radius:3px}.dashboard-bar-chart-container:first-child,.dashboard-full-width-chart .dashboard-full-width-chart-inner:first-child,.dashboard-large-chart .dashboard-large-chart-inner:first-child,.dashboard-medium-chart:first-child,.dashboard-small-chart .dashboard-small-chart-inner:first-child,.dashboard-tendency-container:first-child{margin-left:0}.dashboard-bar-chart-container,.dashboard-full-width-chart,.dashboard-large-chart,.dashboard-medium-chart,.dashboard-small-chart,.dashboard-tendency-container{margin-bottom:10px;position:relative}.dashboard-sub-bar-menu{cursor:pointer;position:absolute;right:9px;top:6px}.dataNotReadyYet{font-family:'Open Sans',sans-serif;font-size:20px;font-weight:100;text-align:center}.dashboard-sub-bar{background-color:#686766;color:#fff;height:24px;line-height:24px;margin:0;padding:0 6px}.dashboard-full-width-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-subtitle-bar.top{border-bottom:1px solid #e1e1e1;height:48px;line-height:48px;text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{border-left:1px solid #e1e1e1}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner{margin-left:10px;margin-right:10px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table{margin-bottom:10px;margin-top:10px;table-layout:fixed;width:100%}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-medium-chart .dashboard-interior-chart{margin-bottom:0}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table .no-data{font-style:italic;font-weight:100}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table tr{border-bottom:1px solid rgba(0,0,0,.025)}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:first-child{width:100px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:last-child{text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart:first-child{border-left:0}.dashboard-full-width-chart .state{background-color:#fff;border-radius:5px;color:#000;margin-left:5px;padding-left:6px;padding-right:4px}.dashboard-large-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-large-chart .dashboard-large-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-small-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-small-chart .dashboard-small-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:5px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart-outer:first-child{margin-right:10px}.dashboard-medium-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;margin-bottom:0;padding-top:10px}.dashboard-medium-chart:first-child{margin-right:12px}.dashboard-medium-chart .dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart .dashboard-medium-chart-menu{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:0 solid rgba(0,0,0,.3);color:rgba(0,0,0,.3);cursor:pointer;padding:0 4px;position:absolute;z-index:1000}.dashboard-medium-chart .dashboard-medium-chart-menu:hover{color:rgba(0,0,0,.7)}.dashboard-medium-chart .dashboard-medium-chart-inner{padding-bottom:10px}.dashboard-medium-chart .clusterChart .slice path{fill-opacity:.15;stroke-opacity:1;stroke-width:1.5px}.dashboard-tendency-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-tendency-container .dashboard-tendency-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{background-color:#fff;margin-top:5px;padding:0 8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency:first-child{border-right:1px solid #e1e1e1}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar{border-bottom:1px solid #e1e1e1;text-align:right}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure{text-align:center}.dashboard-bar-chart-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-bar-chart-container .dashboard-bar-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{margin-top:5px;padding:0 8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{font-weight:400}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{text-align:right}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-legend .dashboard-legend-inner{padding:0 5px 5px 0}.dashboard-spacer{margin:0 12px}.headerBar.dashboard-headerbar{margin:20px 0}.modal-chart-detail .modal-dashboard-legend .dashboard-legend-inner{padding-left:20px}.dashboard-half-height-legend .dashboard-legend-inner{padding-top:20px}.dashboard-title-bar{background-color:#686766;color:#fff;font-size:14.5px;font-weight:400;height:30px;line-height:30px;padding:0 5px 0 10px}.dashboard-title-bar .dashboard-half-title-bar{border-left:1px solid #000;margin-left:-1px;width:50%}.dashboard-title-bar .dashboard-half-title-bar:first-child{border-left:0;margin-left:0}.dashboard-row{margin-bottom:0;margin-left:0;margin-right:0}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{color:#666}.resizecontainer{margin:0 auto}@media (max-width:738px){#arangoCollectionUl{display:none}#collectionsDropdown ul{width:auto!important}#arangoCollectionSelect{display:inline-block;height:29px;margin-top:1px}}@media (min-width:739px) and (max-width:1041px){#arangoCollectionUl a{font-size:12px;height:12px;padding:8px 5px}}@media (min-width:1042px) and (max-width:1284px){#arangoCollectionUl a{font-size:14px}}@media (min-width:250px) and (max-width:489px){.resizecontainer{width:228px}.dashboard-full-width-chart{width:225px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:215px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:69.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:214px}.dashboard-large-chart{width:146px}.dashboard-large-chart .dashboard-sub-bar{width:134px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:136px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:106px}.dashboard-medium-chart{width:96px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:95px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:96px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:79px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:66px}.dashboard-small-chart .dashboard-sub-bar{width:54px}.dashboard-small-chart .dashboard-small-chart-inner{width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:54px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:56px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:40px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-114px;width:248px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:208px}.modal-body .dashboard-large-chart{width:143px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:131px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:133px}.modal-body .dashboard-medium-chart-outer{float:left;width:91px}.modal-body .dashboard-medium-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:89px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:74px}.modal-body .dashboard-small-chart{width:61px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:49px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:51px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:6.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:51px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:56px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:40px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:228px}.application-detail-view aside.meta{display:none}}@media (min-width:490px) and (max-width:729px){.resizecontainer{width:468px}.dashboard-full-width-chart{width:465px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:455px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:149.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart{width:306px}.dashboard-large-chart .dashboard-sub-bar{width:294px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:296px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:226px}.dashboard-medium-chart{width:216px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:215px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:216px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:199px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:146px}.dashboard-small-chart .dashboard-sub-bar{width:134px}.dashboard-small-chart .dashboard-small-chart-inner{width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:48px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:134px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:136px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:120px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-234px;width:488px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:448px}.modal-body .dashboard-large-chart{width:303px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:291px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:293px}.modal-body .dashboard-medium-chart-outer{float:left;width:211px}.modal-body .dashboard-medium-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:194px}.modal-body .dashboard-small-chart{width:141px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:129px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:131px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:46.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:131px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:136px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:120px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:468px}.application-detail-view aside.meta{display:none}}@media (min-width:730px) and (max-width:969px){.resizecontainer{width:708px}.dashboard-full-width-chart{width:705px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:695px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:229.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:694px}.dashboard-large-chart{width:466px}.dashboard-large-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:456px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:346px}.dashboard-medium-chart{width:336px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:335px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:319px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:226px}.dashboard-small-chart .dashboard-sub-bar{width:214px}.dashboard-small-chart .dashboard-small-chart-inner{width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:88px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:214px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:216px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:200px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-354px;width:728px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:688px}.modal-body .dashboard-large-chart{width:463px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:451px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:453px}.modal-body .dashboard-medium-chart-outer{float:left;width:331px}.modal-body .dashboard-medium-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:329px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:314px}.modal-body .dashboard-small-chart{width:221px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:211px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:86.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:211px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:216px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:200px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:508px}}@media (min-width:970px) and (max-width:1209px){.resizecontainer{width:948px}.dashboard-full-width-chart{width:945px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:935px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:309.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart{width:626px}.dashboard-large-chart .dashboard-sub-bar{width:614px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:220px;width:496px}.dashboard-sub-bar-menu{font-size:13px}.dashboard-medium-chart-outer{float:left;width:466px}.dashboard-medium-chart{width:456px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:455px}.dashboard-medium-chart .dashboard-interior-chart{height:220px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:13px;left:438px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:220px;width:456px}.dashboard-medium-chart #clusterGraphs svg text{font-size:11px}.dashboard-small-chart{width:306px}.dashboard-small-chart .dashboard-sub-bar{width:294px}.dashboard-small-chart .dashboard-small-chart-inner{width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:229px;width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:11px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:96.5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:128px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:31.17px;line-height:31.17px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:52.33px;line-height:25.17px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:294px}.dashboard-bar-chart-container{height:98px}.dashboard-bar-chart-container .dashboard-bar-chart{height:96px;width:296px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:31.33px;line-height:31.33px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:45.67px;line-height:45.67px;padding:5px 8px 10px;width:280px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:50.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-474px;width:968px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:13px;min-height:225px;width:130px}.absolut,.percentage{font-size:15px}.modal-chart-detail .modal-inner-detail{width:808px}.modal-body .dashboard-large-chart{width:623px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:611px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:493px}.modal-body .dashboard-medium-chart-outer{float:left;width:451px}.modal-body .dashboard-medium-chart{width:451px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:433px}.modal-body .dashboard-small-chart{width:301px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:289px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:291px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:126.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:291px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:296px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:280px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:11px;font-weight:400}.dashboard-subtitle-bar{font-size:15px;font-weight:300}.dashboard-figure{font-size:18px;font-weight:400}.dashboard-figurePer{font-size:16px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:11px}.dashboard-legend{height:225px;margin-top:-3px;width:120px}.dashboard-half-height-legend{font-size:11px;height:117.5px;width:60px}.application-detail-view section.info{width:748px}}@media (min-width:1210px) and (max-width:1449px){.resizecontainer{width:1188px}.dashboard-full-width-chart{width:1185px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1175px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:389.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1174px}.dashboard-large-chart{width:786px}.dashboard-large-chart .dashboard-sub-bar{width:774px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:255px;width:646px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:586px}.dashboard-medium-chart{width:576px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:575px}.dashboard-medium-chart .dashboard-interior-chart{height:255px;width:446px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:16px;left:555px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:255px;width:576px}.dashboard-medium-chart #clusterGraphs svg text{font-size:12px}.dashboard-small-chart{width:386px}.dashboard-small-chart .dashboard-sub-bar{width:374px}.dashboard-small-chart .dashboard-small-chart-inner{width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:264px;width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:114px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:168px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:37px;line-height:37px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:64px;line-height:31px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:374px}.dashboard-bar-chart-container{height:115.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:113.5px;width:376px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:37.17px;line-height:37.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:57.33px;line-height:57.33px;padding:5px 8px 10px;width:360px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:62.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-594px;width:1208px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:14px;min-height:260px;width:140px}.absolut,.percentage{font-size:18px}.modal-chart-detail .modal-inner-detail{width:1038px}.modal-body .dashboard-large-chart{width:783px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:771px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:643px}.modal-body .dashboard-medium-chart-outer{float:left;width:571px}.modal-body .dashboard-medium-chart{width:571px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:569px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:441px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:550px}.modal-body .dashboard-small-chart{width:381px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:369px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:371px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:166.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:371px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:376px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:360px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:18px;font-weight:300}.dashboard-figure{font-size:22px;font-weight:400}.dashboard-figurePer{font-size:20px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:13px;font-weight:400}.dashboard-legend{font-size:12px;font-weight:400;height:260px;margin-top:-3px;width:130px}.dashboard-half-height-legend{font-size:12px;height:135px;width:65px}.application-detail-view section.info{width:988px}}@media (min-width:1450px) and (max-width:1689px){.resizecontainer{width:1428px}.dashboard-full-width-chart{width:1425px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1415px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:469.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart{width:946px}.dashboard-large-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:796px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:706px}.dashboard-medium-chart{width:696px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:695px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:556px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:18px;left:673px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:696px}.dashboard-medium-chart #clusterGraphs svg text{font-size:13px}.dashboard-small-chart{width:466px}.dashboard-small-chart .dashboard-sub-bar{width:454px}.dashboard-small-chart .dashboard-small-chart-inner{width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:208px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:454px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:456px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:440px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-714px;width:1448px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:15px;min-height:290px;width:150px}.absolut,.percentage{font-size:20px}.modal-chart-detail .modal-inner-detail{width:1268px}.modal-body .dashboard-large-chart{width:943px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:931px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:793px}.modal-body .dashboard-medium-chart-outer{float:left;width:691px}.modal-body .dashboard-medium-chart{width:691px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:551px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:668px}.modal-body .dashboard-small-chart{width:461px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:451px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:206.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:451px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:456px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:440px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:20px;font-weight:300}.dashboard-figure{font-size:26px;font-weight:400}.dashboard-figurePer{font-size:24px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:13px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:13px;height:150px;width:70px}.application-detail-view section.info{width:1228px}}@media (min-width:1690px) and (max-width:1929px){.resizecontainer{width:1668px}.dashboard-full-width-chart{width:1665px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1655px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:549.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1654px}.dashboard-large-chart{width:1106px}.dashboard-large-chart .dashboard-sub-bar{width:1094px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:325px;width:936px}.dashboard-sub-bar-menu{font-size:16px}.dashboard-medium-chart-outer{float:left;width:826px}.dashboard-medium-chart{width:816px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:815px}.dashboard-medium-chart .dashboard-interior-chart{height:325px;width:656px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:22px;left:789px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:325px;width:816px}.dashboard-medium-chart #clusterGraphs svg text{font-size:14px}.dashboard-small-chart{width:546px}.dashboard-small-chart .dashboard-sub-bar{width:534px}.dashboard-small-chart .dashboard-small-chart-inner{width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:334px;width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:149px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:248px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:48.67px;line-height:48.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:87.33px;line-height:42.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:534px}.dashboard-bar-chart-container{height:150.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:148.5px;width:536px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:48.83px;line-height:48.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:80.67px;line-height:80.67px;padding:5px 8px 10px;width:520px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:85.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-834px;width:1688px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:16px;min-height:330px;width:170px}.absolut,.percentage{font-size:24px}.modal-chart-detail .modal-inner-detail{width:1488px}.modal-body .dashboard-large-chart{width:1103px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1091px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:933px}.modal-body .dashboard-medium-chart-outer{float:left;width:811px}.modal-body .dashboard-medium-chart{width:811px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:809px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:651px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:784px}.modal-body .dashboard-small-chart{width:541px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:529px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:531px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:246.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:531px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:536px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:520px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:14px;font-weight:400}.dashboard-subtitle-bar{font-size:24px;font-weight:300}.dashboard-figure{font-size:30px;font-weight:400}.dashboard-figurePer{font-size:28px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:14px}.dashboard-legend{height:330px;margin-top:-3px;width:160px}.dashboard-half-height-legend{font-size:14px;height:170px;width:80px}.application-detail-view section.info{width:1468px}}@media (min-width:1930px) and (max-width:2169px){.resizecontainer{width:1908px}.dashboard-full-width-chart{width:1905px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1895px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:629.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1894px}.dashboard-large-chart{width:1266px}.dashboard-large-chart .dashboard-sub-bar{width:1254px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:385px;width:1086px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:946px}.dashboard-medium-chart{width:936px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:935px}.dashboard-medium-chart .dashboard-interior-chart{height:385px;width:766px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:26px;left:905px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:385px;width:936px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:626px}.dashboard-small-chart .dashboard-sub-bar{width:614px}.dashboard-small-chart .dashboard-small-chart-inner{width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:394px;width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:179px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:288px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:58.67px;line-height:58.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:107.33px;line-height:52.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:614px}.dashboard-bar-chart-container{height:180.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:178.5px;width:616px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:58.83px;line-height:58.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:100.67px;line-height:100.67px;padding:5px 8px 10px;width:600px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:105.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-954px;width:1928px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:390px;width:180px}.absolut,.percentage{font-size:28px}.modal-chart-detail .modal-inner-detail{width:1718px}.modal-body .dashboard-large-chart{width:1263px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1251px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1083px}.modal-body .dashboard-medium-chart-outer{float:left;width:931px}.modal-body .dashboard-medium-chart{width:931px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:929px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:761px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:900px}.modal-body .dashboard-small-chart{width:621px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:609px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:611px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:286.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:611px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:616px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:600px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:28px;font-weight:300}.dashboard-figure{font-size:34px;font-weight:400}.dashboard-figurePer{font-size:32px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:14px;font-weight:400}.dashboard-legend{font-size:15px;font-weight:400;height:390px;margin-top:-3px;width:170px}.dashboard-half-height-legend{font-size:15px;height:200px;width:85px}.application-detail-view section.info{width:1708px}}@media (min-width:2170px) and (max-width:2409px){.resizecontainer{width:2148px}.dashboard-full-width-chart{width:2145px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2135px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:709.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2134px}.dashboard-large-chart{width:1426px}.dashboard-large-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1276px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1066px}.dashboard-medium-chart{width:1056px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1055px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:916px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1031px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1056px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:706px}.dashboard-small-chart .dashboard-sub-bar{width:694px}.dashboard-small-chart .dashboard-small-chart-inner{width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:328px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:694px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:696px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:680px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1074px;width:2168px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:1988px}.modal-body .dashboard-large-chart{width:1423px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1411px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1273px}.modal-body .dashboard-medium-chart-outer{float:left;width:1051px}.modal-body .dashboard-medium-chart{width:1051px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1049px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:911px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1026px}.modal-body .dashboard-small-chart{width:701px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:691px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:326.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:691px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:696px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:680px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:1948px}}@media (min-width:2410px) and (max-width:2649px){.resizecontainer{width:2388px}.dashboard-full-width-chart{width:2385px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2375px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:789.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2374px}.dashboard-large-chart{width:1586px}.dashboard-large-chart .dashboard-sub-bar{width:1574px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1436px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1186px}.dashboard-medium-chart{width:1176px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1175px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1036px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1151px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1176px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:786px}.dashboard-small-chart .dashboard-sub-bar{width:774px}.dashboard-small-chart .dashboard-small-chart-inner{width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:368px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:774px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:776px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:760px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1194px;width:2408px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2228px}.modal-body .dashboard-large-chart{width:1583px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1571px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1433px}.modal-body .dashboard-medium-chart-outer{float:left;width:1171px}.modal-body .dashboard-medium-chart{width:1171px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1169px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1031px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1146px}.modal-body .dashboard-small-chart{width:781px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:769px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:771px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:366.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:771px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:776px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:760px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2188px}}@media (min-width:2650px) and (max-width:2889px){.resizecontainer{width:2628px}.dashboard-full-width-chart{width:2625px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2615px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:869.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2614px}.dashboard-large-chart{width:1746px}.dashboard-large-chart .dashboard-sub-bar{width:1734px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1596px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1306px}.dashboard-medium-chart{width:1296px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1295px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1156px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1271px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1296px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:866px}.dashboard-small-chart .dashboard-sub-bar{width:854px}.dashboard-small-chart .dashboard-small-chart-inner{width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:408px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:854px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:856px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:840px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1314px;width:2648px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2468px}.modal-body .dashboard-large-chart{width:1743px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1731px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1593px}.modal-body .dashboard-medium-chart-outer{float:left;width:1291px}.modal-body .dashboard-medium-chart{width:1291px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1289px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1151px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1266px}.modal-body .dashboard-small-chart{width:861px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:849px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:851px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:406.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:851px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:856px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:840px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2428px}}div.centralRow{margin-bottom:40px;margin-top:40px}div.centralContent{background-color:transparent;height:100%;margin-left:-5px;margin-right:-5px;min-height:80px;padding:5px;width:100%}.contentDiv{list-style:none;padding:13px 0 0}.contentDiv li{background-color:rgba(0,0,0,.05)}.contentDiv a.add{display:block;font-weight:400;padding:40px 0;text-align:left}.contentDiv .icon{padding-left:5px;padding-right:5px;padding-top:10px}.contentDiv:after{clear:both}.contentDiv:after,.contentDiv:before{content:'';display:table;line-height:0}body{background-color:rgba(245,248,240,.95)}.headerButtonBar select{border:1px solid rgba(140,138,137,.25);height:28px} \ No newline at end of file diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css.gz b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css.gz index 45acccb957..b72c83e4c2 100644 Binary files a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css.gz and b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css.gz differ diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css index 06b86bdfc4..ce0ccce0e2 100644 --- a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css +++ b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css @@ -2907,8 +2907,33 @@ div .tile, div .bigtile { position: relative; text-align: center; z-index: 1; } + div .tile progress[value], div .bigtile progress[value] { + color: #5bc0de; } + div .tile progress::-webkit-progress-bar-value, div .bigtile progress::-webkit-progress-bar-value { + background: #5bc0de; } + div .tile progress::-webkit-progress-value, div .bigtile progress::-webkit-progress-value { + background: #5bc0de; } + div .tile progress::-moz-progress-bar, div .bigtile progress::-moz-progress-bar { + background: #5bc0de; } + div .tile progress, div .bigtile progress { + -webkit-appearance: none; + border-radius: 0; + height: 2px; + margin-top: 16px; + position: relative; + width: 100%; + z-index: 10; } div .tile:hover, div .bigtile:hover { cursor: pointer; } + div .locked.tile, div .locked.bigtile { + cursor: not-allowed; + opacity: .5; } + div .locked.tile .iconSet span:hover, div .locked.bigtile .iconSet span:hover { + background-color: #fff !important; + color: #000; + cursor: not-allowed !important; } + div .locked.tile .iconSet:hover, div .locked.bigtile .iconSet:hover { + cursor: not-allowed !important; } div .tile .warning-icons, div .bigtile .warning-icons { background-color: #da4f49; border-radius: 3px; @@ -2980,6 +3005,8 @@ div .tile, div .bigtile { padding: 4px 8px; text-overflow: ellipsis !important; white-space: nowrap !important; } + div .tile h5.inProgress, div .bigtile h5.inProgress { + color: #5bc0de; } div .tile .tileSelects, div .bigtile .tileSelects { margin-left: 40px; position: relative; @@ -5498,7 +5525,7 @@ div.headerBar { z-index: 9999999; } .modal-tabbar { - border-bottom: 1px solid #000; } + border-bottom: 1px solid #666; } .modal-body { color: #736b68; @@ -5923,8 +5950,33 @@ div .tile, div .bigtile { position: relative; text-align: center; z-index: 1; } + div .tile progress[value], div .bigtile progress[value] { + color: #5bc0de; } + div .tile progress::-webkit-progress-bar-value, div .bigtile progress::-webkit-progress-bar-value { + background: #5bc0de; } + div .tile progress::-webkit-progress-value, div .bigtile progress::-webkit-progress-value { + background: #5bc0de; } + div .tile progress::-moz-progress-bar, div .bigtile progress::-moz-progress-bar { + background: #5bc0de; } + div .tile progress, div .bigtile progress { + -webkit-appearance: none; + border-radius: 0; + height: 2px; + margin-top: 16px; + position: relative; + width: 100%; + z-index: 10; } div .tile:hover, div .bigtile:hover { cursor: pointer; } + div .locked.tile, div .locked.bigtile { + cursor: not-allowed; + opacity: .5; } + div .locked.tile .iconSet span:hover, div .locked.bigtile .iconSet span:hover { + background-color: #fff !important; + color: #000; + cursor: not-allowed !important; } + div .locked.tile .iconSet:hover, div .locked.bigtile .iconSet:hover { + cursor: not-allowed !important; } div .tile .warning-icons, div .bigtile .warning-icons { background-color: #da4f49; border-radius: 3px; @@ -5996,6 +6048,8 @@ div .tile, div .bigtile { padding: 4px 8px; text-overflow: ellipsis !important; white-space: nowrap !important; } + div .tile h5.inProgress, div .bigtile h5.inProgress { + color: #5bc0de; } div .tile .tileSelects, div .bigtile .tileSelects { margin-left: 40px; position: relative; diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css.gz b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css.gz index f2121d2eac..918366d666 100644 Binary files a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css.gz and b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style.css.gz differ diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/app.js b/js/apps/system/_admin/aardvark/APP/frontend/build/app.js index 9d50e4fb10..307622717a 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/build/app.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/build/app.js @@ -10756,15 +10756,15 @@ function GraphViewer(svg, width, height, adapterConfig, config) { }); if (found) { - this.deleteAardvarkJob(aardvark.id); - } - else { array.push({ collection: aardvark.collection, id: aardvark.id, type: aardvark.type }); } + else { + window.arangoHelper.deleteAardvarkJob(aardvark.id); + } } }); } @@ -16435,7 +16435,8 @@ var __fs__=require("fs");var __rcf__=__fs__.join(__fs__.home(),".arangosh.rc");i status: "", type: "", isSystem: false, - picture: "" + picture: "", + locked: false }, getProperties: function () { @@ -16553,14 +16554,14 @@ var __fs__=require("fs");var __rcf__=__fs__.join(__fs__.home(),".arangosh.rc");i cache: false, type: 'DELETE', url: "/_api/index/"+ this.get("name") +"/"+encodeURIComponent(id), - async: false, + async: true, success: function () { callback(false); }, error: function (data) { callback(true, data); } - }); + }); callback(); }, @@ -19530,19 +19531,29 @@ window.ArangoUsers = Backbone.Collection.extend({ }, render: function () { + if (this.model.get("locked")) { + $(this.el).addClass('locked'); + } $(this.el).html(this.template.render({ model: this.model })); $(this.el).attr('id', 'collection_' + this.model.get('name')); + return this; }, editProperties: function (event) { + if (this.model.get("locked")) { + return 0; + } event.stopPropagation(); this.createEditPropertiesModal(); }, showProperties: function(event) { + if (this.model.get("locked")) { + return 0; + } event.stopPropagation(); this.createInfoModal(); }, @@ -19553,6 +19564,9 @@ window.ArangoUsers = Backbone.Collection.extend({ if ($(event.target).hasClass("disabled")) { return 0; } + if (this.model.get("locked")) { + return 0; + } window.App.navigate( "collection/" + encodeURIComponent(this.model.get("name")) + "/documents/1", {trigger: true} @@ -19863,7 +19877,12 @@ window.ArangoUsers = Backbone.Collection.extend({ this.events, null, tabBar ); - this.getIndex(); + if (this.model.get("status") === 'loaded') { + this.getIndex(); + } + else { + $($('#infoTab').children()[1]).remove(); + } this.bindIndexEvents(); }, @@ -19895,6 +19914,7 @@ window.ArangoUsers = Backbone.Collection.extend({ }); $('#infoTab a').bind('click', function(e) { + $('#indexDeleteModal').remove(); if ($(e.currentTarget).html() === 'Indices' && !$(e.currentTarget).parent().hasClass('active')) { $('#newIndexView').hide(); @@ -20019,7 +20039,6 @@ window.ArangoUsers = Backbone.Collection.extend({ break; } var callback = function(error, msg){ - if (error) { if (msg) { var message = JSON.parse(msg.responseText); @@ -20032,10 +20051,15 @@ window.ArangoUsers = Backbone.Collection.extend({ }; window.modalView.hide(); - this.getIndex(); - this.createEditPropertiesModal(); - $($('#infoTab').children()[1]).find('a').click(); + //this.getIndex(); + //this.createEditPropertiesModal(); + //$($('#infoTab').children()[1]).find('a').click(); self.model.createIndex(postParameter, callback); + window.App.arangoCollectionsStore.fetch({ + success: function () { + self.collectionsView.render(); + } + }); }, lastTarget: null, @@ -20051,27 +20075,47 @@ window.ArangoUsers = Backbone.Collection.extend({ children(). first(). text(); - window.modalView.hide(); + //window.modalView.hide(); //delete modal - $("#indexDeleteModal").modal('show'); - $('#confirmDeleteIndexBtn').unbind('click'); - $('#confirmDeleteIndexBtn').bind('click', function() { + $("#modal-dialog .modal-footer").after( + ''); + $('#indexConfirmDelete').unbind('click'); + $('#indexConfirmDelete').bind('click', function() { + $('#indexDeleteModal').remove(); self.deleteIndex(); }); + + $('#indexAbortDelete').unbind('click'); + $('#indexAbortDelete').bind('click', function() { + $('#indexDeleteModal').remove(); + }); + + }, deleteIndex: function () { var callback = function(error) { if (error) { arangoHelper.arangoError("Could not delete index"); + $("tr th:contains('"+ this.lastId+"')").parent().children().last().html( + '' + ); } - }; + else { + $("tr th:contains('"+ this.lastId+"')").parent().remove(); + } + }.bind(this); - $("#indexDeleteModal").modal('hide'); this.model.deleteIndex(this.lastId, callback); - this.createEditPropertiesModal(); - $($('#infoTab').children()[1]).find('a').click(); + $("tr th:contains('"+ this.lastId+"')").parent().children().last().html( + '' + ); }, selectIndexType: function () { @@ -20138,7 +20182,6 @@ window.ArangoUsers = Backbone.Collection.extend({ } else { - console.log("toggle else"); $('#indexEditView').show(); $('#newIndexView').hide(); $('#addIndex').detach().appendTo('#modal-dialog .modal-footer'); @@ -20179,13 +20222,51 @@ window.ArangoUsers = Backbone.Collection.extend({ el2: '#collectionsThumbnailsIn', searchTimeout: null, + refreshRate: 2000, template: templateEngine.createTemplate("collectionsView.ejs"), + checkLockedCollections: function() { + + var self = this, + lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index'); + + this.collection.each(function(model) { + model.set('locked', false); + }); + + _.each(lockedCollections, function(locked) { + var model = self.collection.findWhere({ + id: locked.collection + }); + model.set('locked', true); + model.set('lockType', locked.type); + }); + + this.collection.each(function(model) { + if (model.get("locked")) { + $('#collection_' + model.get("name")).addClass('locked'); + } + else { + $('#collection_' + model.get("name")).removeClass('locked'); + } + }); + + }, + + initialize: function() { + var self = this; + + window.setInterval(function() { + self.checkLockedCollections(); + }, self.refreshRate); + + }, + render: function () { - var dropdownVisible = false, - lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index'); + this.checkLockedCollections(); + var dropdownVisible = false; if ($('#collectionsDropdown').is(':visible')) { dropdownVisible = true; @@ -20231,6 +20312,7 @@ window.ArangoUsers = Backbone.Collection.extend({ arangoHelper.fixTooltips(".icon_arangodb, .arangoicon", "left"); + return this; }, @@ -20457,7 +20539,7 @@ window.ArangoUsers = Backbone.Collection.extend({ var returnobj = this.collection.newCollection( collName, wfs, isSystem, collSize, collType, shards, shardBy ); - if (returnobj.status !== true) {console.log(returnobj); + if (returnobj.status !== true) { arangoHelper.arangoError("Collection error", returnobj.errorMessage); } this.updateCollectionsView(); diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/app.js.gz b/js/apps/system/_admin/aardvark/APP/frontend/build/app.js.gz index 1118306bc2..e40d940da9 100644 Binary files a/js/apps/system/_admin/aardvark/APP/frontend/build/app.js.gz and b/js/apps/system/_admin/aardvark/APP/frontend/build/app.js.gz differ diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/standalone-min.html b/js/apps/system/_admin/aardvark/APP/frontend/build/standalone-min.html index 399173d0f1..6852497622 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/build/standalone-min.html +++ b/js/apps/system/_admin/aardvark/APP/frontend/build/standalone-min.html @@ -264,7 +264,13 @@ -
<%= model.get('name') %>
diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs index d0d899121a..3abb90de72 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs @@ -115,19 +115,4 @@ - - - diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js index 949e7f98a2..598ce69cab 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js @@ -24,19 +24,29 @@ }, render: function () { + if (this.model.get("locked")) { + $(this.el).addClass('locked'); + } $(this.el).html(this.template.render({ model: this.model })); $(this.el).attr('id', 'collection_' + this.model.get('name')); + return this; }, editProperties: function (event) { + if (this.model.get("locked")) { + return 0; + } event.stopPropagation(); this.createEditPropertiesModal(); }, showProperties: function(event) { + if (this.model.get("locked")) { + return 0; + } event.stopPropagation(); this.createInfoModal(); }, @@ -47,6 +57,9 @@ if ($(event.target).hasClass("disabled")) { return 0; } + if (this.model.get("locked")) { + return 0; + } window.App.navigate( "collection/" + encodeURIComponent(this.model.get("name")) + "/documents/1", {trigger: true} @@ -357,7 +370,12 @@ this.events, null, tabBar ); - this.getIndex(); + if (this.model.get("status") === 'loaded') { + this.getIndex(); + } + else { + $($('#infoTab').children()[1]).remove(); + } this.bindIndexEvents(); }, @@ -389,6 +407,7 @@ }); $('#infoTab a').bind('click', function(e) { + $('#indexDeleteModal').remove(); if ($(e.currentTarget).html() === 'Indices' && !$(e.currentTarget).parent().hasClass('active')) { $('#newIndexView').hide(); @@ -513,7 +532,6 @@ break; } var callback = function(error, msg){ - if (error) { if (msg) { var message = JSON.parse(msg.responseText); @@ -526,10 +544,15 @@ }; window.modalView.hide(); - this.getIndex(); - this.createEditPropertiesModal(); - $($('#infoTab').children()[1]).find('a').click(); + //this.getIndex(); + //this.createEditPropertiesModal(); + //$($('#infoTab').children()[1]).find('a').click(); self.model.createIndex(postParameter, callback); + window.App.arangoCollectionsStore.fetch({ + success: function () { + self.collectionsView.render(); + } + }); }, lastTarget: null, @@ -545,27 +568,47 @@ children(). first(). text(); - window.modalView.hide(); + //window.modalView.hide(); //delete modal - $("#indexDeleteModal").modal('show'); - $('#confirmDeleteIndexBtn').unbind('click'); - $('#confirmDeleteIndexBtn').bind('click', function() { + $("#modal-dialog .modal-footer").after( + ''); + $('#indexConfirmDelete').unbind('click'); + $('#indexConfirmDelete').bind('click', function() { + $('#indexDeleteModal').remove(); self.deleteIndex(); }); + + $('#indexAbortDelete').unbind('click'); + $('#indexAbortDelete').bind('click', function() { + $('#indexDeleteModal').remove(); + }); + + }, deleteIndex: function () { var callback = function(error) { if (error) { arangoHelper.arangoError("Could not delete index"); + $("tr th:contains('"+ this.lastId+"')").parent().children().last().html( + '' + ); } - }; + else { + $("tr th:contains('"+ this.lastId+"')").parent().remove(); + } + }.bind(this); - $("#indexDeleteModal").modal('hide'); this.model.deleteIndex(this.lastId, callback); - this.createEditPropertiesModal(); - $($('#infoTab').children()[1]).find('a').click(); + $("tr th:contains('"+ this.lastId+"')").parent().children().last().html( + '' + ); }, selectIndexType: function () { @@ -632,7 +675,6 @@ } else { - console.log("toggle else"); $('#indexEditView').show(); $('#newIndexView').hide(); $('#addIndex').detach().appendTo('#modal-dialog .modal-footer'); diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js index a8a3538ce9..d1b2cee45a 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js @@ -9,13 +9,51 @@ el2: '#collectionsThumbnailsIn', searchTimeout: null, + refreshRate: 2000, template: templateEngine.createTemplate("collectionsView.ejs"), + checkLockedCollections: function() { + + var self = this, + lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index'); + + this.collection.each(function(model) { + model.set('locked', false); + }); + + _.each(lockedCollections, function(locked) { + var model = self.collection.findWhere({ + id: locked.collection + }); + model.set('locked', true); + model.set('lockType', locked.type); + }); + + this.collection.each(function(model) { + if (model.get("locked")) { + $('#collection_' + model.get("name")).addClass('locked'); + } + else { + $('#collection_' + model.get("name")).removeClass('locked'); + } + }); + + }, + + initialize: function() { + var self = this; + + window.setInterval(function() { + self.checkLockedCollections(); + }, self.refreshRate); + + }, + render: function () { - var dropdownVisible = false, - lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index'); + this.checkLockedCollections(); + var dropdownVisible = false; if ($('#collectionsDropdown').is(':visible')) { dropdownVisible = true; @@ -61,6 +99,7 @@ arangoHelper.fixTooltips(".icon_arangodb, .arangoicon", "left"); + return this; }, @@ -287,7 +326,7 @@ var returnobj = this.collection.newCollection( collName, wfs, isSystem, collSize, collType, shards, shardBy ); - if (returnobj.status !== true) {console.log(returnobj); + if (returnobj.status !== true) { arangoHelper.arangoError("Collection error", returnobj.errorMessage); } this.updateCollectionsView(); diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss index c601a99b12..4a7e06af97 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss @@ -117,12 +117,19 @@ margin-bottom: 1px; padding-bottom: 0; padding-right: 10px; + } #infoTab li, #graphTab li, #collectionTab li { float: right; + + &.disabled { + a { + cursor: not-allowed; + } + } } #infoTab a, diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss index 5c677dbfe3..9fa9ca2c6c 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss @@ -148,6 +148,7 @@ $c-sh-string: #ce2f30; $c-sh-object: #00f; $c-sh-array: #00f; +$c-progress-bar: #5bc0de; $c-progress-shadow: #353c39; $c-progress-shadow-2: #8cdb8b; $c-progress-bg: #363c39; diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss index 4130a848ba..a83449317a 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss @@ -5,7 +5,6 @@ .new-index-view { input[type='checkbox'] { float: left; - margin-top: -9px; } table { @@ -67,7 +66,18 @@ .newIndexClass { table { + border-top: 1px solid $c-modal-table-border-bottom; margin-bottom: 60px; + + select { + margin-right: 7px; + } + + .arangoicon { + float: right; + margin-right: -12px; + margin-top: 5px; + } } } diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss index 416d294520..037829924b 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss @@ -39,7 +39,7 @@ } .modal-tabbar { - border-bottom: 1px solid $c-black; + border-bottom: 1px solid $c-darker-grey; } .modal-body { diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss index 6cbeb9271f..7d7de761bd 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss @@ -39,10 +39,53 @@ $iconsize: 50px; z-index: 1; + progress[value] { + color: $c-progress-bar; + } + + progress::-webkit-progress-bar-value { + background: $c-progress-bar; + } + + progress::-webkit-progress-value { + background: $c-progress-bar; + } + + progress::-moz-progress-bar { + background: $c-progress-bar; + } + + progress { + -webkit-appearance: none; + border-radius: 0; + height: 2px; + margin-top: 16px; + position: relative; + width: 100%; + z-index: 10; + } + &:hover { cursor: pointer; } + &.locked { + cursor: not-allowed; + opacity: .5; + + .iconSet { + span:hover { + background-color: $c-white !important; + color: $c-black; + cursor: not-allowed !important; + } + } + + .iconSet:hover { + cursor: not-allowed !important; + } + } + .warning-icons { background-color: $c-negative; border-radius: 3px; @@ -153,6 +196,10 @@ $iconsize: 50px; padding: 4px 8px; text-overflow: ellipsis !important; white-space: nowrap !important; + + &.inProgress { + color: $c-progress-bar; + } } .tileSelects { diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index ecc78d3068..61ece84fdb 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -257,31 +257,14 @@ "SIMPLE_CLIENT_COULD_NOT_READ" : { "code" : 2003, "message" : "could not read from server" }, "ERROR_MALFORMED_MANIFEST_FILE" : { "code" : 3000, "message" : "malformed manifest file" }, "ERROR_INVALID_APPLICATION_MANIFEST" : { "code" : 3001, "message" : "manifest file is invalid" }, - "ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING" : { "code" : 3002, "message" : "missing manifest attribute" }, - "ERROR_CANNOT_EXTRACT_APPLICATION_ROOT" : { "code" : 3003, "message" : "unable to extract app root path" }, "ERROR_INVALID_FOXX_OPTIONS" : { "code" : 3004, "message" : "invalid foxx options" }, - "ERROR_FAILED_TO_EXECUTE_SCRIPT" : { "code" : 3005, "message" : "failed to execute script" }, - "ERROR_SYNTAX_ERROR_IN_SCRIPT" : { "code" : 3006, "message" : "syntax error in script" }, "ERROR_INVALID_MOUNTPOINT" : { "code" : 3007, "message" : "mountpoint is invalid" }, - "ERROR_NO_FOXX_FOUND" : { "code" : 3008, "message" : "No foxx found at this location" }, "ERROR_APP_NOT_FOUND" : { "code" : 3009, "message" : "App not found" }, "ERROR_APP_NEEDS_CONFIGURATION" : { "code" : 3010, "message" : "App not configured" }, "ERROR_MODULE_NOT_FOUND" : { "code" : 3100, "message" : "cannot locate module" }, - "ERROR_MODULE_SYNTAX_ERROR" : { "code" : 3101, "message" : "syntax error in module" }, - "ERROR_MODULE_BAD_WRAPPER" : { "code" : 3102, "message" : "failed to wrap module" }, "ERROR_MODULE_FAILURE" : { "code" : 3103, "message" : "failed to invoke module" }, - "ERROR_MODULE_UNKNOWN_FILE_TYPE" : { "code" : 3110, "message" : "unknown file type" }, - "ERROR_MODULE_PATH_MUST_BE_ABSOLUTE" : { "code" : 3111, "message" : "path must be absolute" }, - "ERROR_MODULE_CAN_NOT_ESCAPE" : { "code" : 3112, "message" : "cannot use '..' to escape top-level-directory" }, - "ERROR_MODULE_DRIVE_LETTER" : { "code" : 3113, "message" : "drive local path is not supported" }, - "ERROR_MODULE_BAD_MODULE_ORIGIN" : { "code" : 3120, "message" : "corrupted module origin" }, - "ERROR_MODULE_BAD_PACKAGE_ORIGIN" : { "code" : 3121, "message" : "corrupted package origin" }, - "ERROR_MODULE_DOCUMENT_IS_EMPTY" : { "code" : 3125, "message" : "no content" }, - "ERROR_MODULE_MAIN_NOT_READABLE" : { "code" : 3130, "message" : "cannot read main file" }, - "ERROR_MODULE_MAIN_NOT_JS" : { "code" : 3131, "message" : "main file is not of type 'js'" }, "RESULT_ELEMENT_EXISTS" : { "code" : 10000, "message" : "element not inserted into structure, because it already exists" }, "RESULT_ELEMENT_NOT_FOUND" : { "code" : 10001, "message" : "element not found in structure" }, - "ERROR_APP_ALREADY_EXISTS" : { "code" : 20000, "message" : "newest version of app already installed" }, "ERROR_QUEUE_ALREADY_EXISTS" : { "code" : 21000, "message" : "named queue already exists" }, "ERROR_DISPATCHER_IS_STOPPING" : { "code" : 21001, "message" : "dispatcher stopped" }, "ERROR_QUEUE_UNKNOWN" : { "code" : 21002, "message" : "named queue does not exist" }, diff --git a/js/common/tests/shell/shell-statement.js b/js/common/tests/shell/shell-statement.js index 13a6f39882..4734e73391 100644 --- a/js/common/tests/shell/shell-statement.js +++ b/js/common/tests/shell/shell-statement.js @@ -497,7 +497,14 @@ function StatementSuite () { while (result.hasNext()) { var doc = result.next(); assertEqual([ { b: 2 } ], doc.missing); - assertEqual([ { foo: { "old": "bar", "new": "baz" } }, { a: { "old" : 1, "new": 2 } } ], doc.changed); + var changed = doc.changed; + if (changed[0].hasOwnProperty("foo")) { + assertEqual({ foo: { "old": "bar", "new": "baz" } }, changed[0]); + assertEqual({ a: { "old" : 1, "new": 2 } }, doc.changed[1]); + } else { + assertEqual({ a: { "old" : 1, "new": 2 } }, changed[0]); + assertEqual({ foo: { "old": "bar", "new": "baz" } }, changed[1]); + } assertEqual([ { c: 3 } ], doc.added); } }, diff --git a/js/server/tests/aql/aql-functions-numeric.js b/js/server/tests/aql/aql-functions-numeric.js index 8faaf6308c..9fd7b93843 100644 --- a/js/server/tests/aql/aql-functions-numeric.js +++ b/js/server/tests/aql/aql-functions-numeric.js @@ -138,13 +138,23 @@ function ahuacatlNumericFunctionsTestSuite () { testAbs : function () { var expected = [ 99.999, 3, 2.1, 2.01, 2, 1.99, 1.1, 1.01, 1, 0.9, 0.6, 0.5, 0.4, 0.1, 0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ]; var actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return ABS(r)"); - assertEqual(expected, actual); + var i = 0; + assertEqual(actual.length, expected.length); + for (i = 0; i < expected.length; ++i) { + assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5)); + } actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return NOOPT(ABS(r))"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + for (i = 0; i < expected.length; ++i) { + assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5)); + } actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return NOOPT(V8(ABS(r)))"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + for (i = 0; i < expected.length; ++i) { + assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5)); + } }, //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/tests/aql/aql-functions-types-cxx.js b/js/server/tests/aql/aql-functions-types-cxx.js index 50d3fa9db3..d9a912c815 100644 --- a/js/server/tests/aql/aql-functions-types-cxx.js +++ b/js/server/tests/aql/aql-functions-types-cxx.js @@ -498,9 +498,13 @@ function ahuacatlTypesFunctionsTestSuite () { //////////////////////////////////////////////////////////////////////////////// testToArray5 : function () { - var expected = [ [ -0.635 ] ]; + var expected = -0.635; var actual = getQueryResults("RETURN NOOPT(TO_ARRAY(-0.635))"); - assertEqual(expected, actual); + assertEqual(actual.length, 1); + assertEqual(actual[0].length, 1); + var value = actual[0][0]; + // Double precission + assertEqual(expected.toPrecision(5), value.toPrecision(5)); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/tests/aql/aql-functions.js b/js/server/tests/aql/aql-functions.js index be2df77d46..a8b3404d32 100644 --- a/js/server/tests/aql/aql-functions.js +++ b/js/server/tests/aql/aql-functions.js @@ -3272,7 +3272,10 @@ function ahuacatlFunctionsTestSuite () { testAttributes1 : function () { var expected = [ [ "foo", "bar", "meow", "_id" ], [ "foo" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN ATTRIBUTES(u)"); - assertEqual(expected, actual); + // Order is not guaranteed order here in-place + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3282,7 +3285,10 @@ function ahuacatlFunctionsTestSuite () { testAttributes2 : function () { var expected = [ [ "foo", "bar", "meow" ], [ "foo" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN ATTRIBUTES(u, true)"); - assertEqual(expected, actual); + // Order is not guaranteed order here in-place + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3312,7 +3318,10 @@ function ahuacatlFunctionsTestSuite () { testAttributesCxx1 : function () { var expected = [ [ "foo", "bar", "meow", "_id" ], [ "foo" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(ATTRIBUTES(u))"); - assertEqual(expected, actual); + // Order is not guaranteed order here in-place + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3322,7 +3331,10 @@ function ahuacatlFunctionsTestSuite () { testAttributesCxx2 : function () { var expected = [ [ "foo", "bar", "meow" ], [ "foo" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(ATTRIBUTES(u, true))"); - assertEqual(expected, actual); + // Order is not guaranteed order here in-place + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3352,7 +3364,9 @@ function ahuacatlFunctionsTestSuite () { testValues1 : function () { var expected = [ [ "bar", "baz", true, "123/456" ], [ "bar" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN VALUES(u)"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3362,7 +3376,9 @@ function ahuacatlFunctionsTestSuite () { testValues2 : function () { var expected = [ [ "bar", "baz", true ], [ "bar" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN VALUES(u, true)"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3372,7 +3388,8 @@ function ahuacatlFunctionsTestSuite () { testValues3 : function () { var expected = [ [ "test/1123", "test/abc", "1234", "test", "", [ 1, 2, 3, 4, [ true ] ], null, { d: 42, e: null, f: [ "test!" ] } ] ]; var actual = getQueryResults("RETURN VALUES({ _from: \"test/1123\", _to: \"test/abc\", _rev: \"1234\", _key: \"test\", void: \"\", a: [ 1, 2, 3, 4, [ true ] ], b : null, c: { d: 42, e: null, f: [ \"test!\" ] } })"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3382,7 +3399,9 @@ function ahuacatlFunctionsTestSuite () { testValuesCxx1 : function () { var expected = [ [ "bar", "baz", true, "123/456" ], [ "bar" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(VALUES(u))"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3392,7 +3411,9 @@ function ahuacatlFunctionsTestSuite () { testValuesCxx2 : function () { var expected = [ [ "bar", "baz", true ], [ "bar" ] ]; var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(VALUES(u, true))"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); + assertEqual(actual[1].sort(), expected[1].sort()); }, //////////////////////////////////////////////////////////////////////////////// @@ -3402,7 +3423,8 @@ function ahuacatlFunctionsTestSuite () { testValuesCxx3 : function () { var expected = [ [ "test/1123", "test/abc", "1234", "test", "", [ 1, 2, 3, 4, [ true ] ], null, { d: 42, e: null, f: [ "test!" ] } ] ]; var actual = getQueryResults("RETURN NOOPT(VALUES({ _from: \"test/1123\", _to: \"test/abc\", _rev: \"1234\", _key: \"test\", void: \"\", a: [ 1, 2, 3, 4, [ true ] ], b : null, c: { d: 42, e: null, f: [ \"test!\" ] } }))"); - assertEqual(expected, actual); + assertEqual(actual.length, expected.length); + assertEqual(actual[0].sort(), expected[0].sort()); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/tests/aql/aql-operators.js b/js/server/tests/aql/aql-operators.js index 9dae488928..61a9bb070e 100644 --- a/js/server/tests/aql/aql-operators.js +++ b/js/server/tests/aql/aql-operators.js @@ -30,34 +30,32 @@ var jsunity = require("jsunity"); var aql = require("@arangodb/aql"); +var db = require("internal").db; //////////////////////////////////////////////////////////////////////////////// /// @brief test suite //////////////////////////////////////////////////////////////////////////////// function ahuacatlOperatorsTestSuite () { - return { -//////////////////////////////////////////////////////////////////////////////// -/// @brief set up -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief set up + //////////////////////////////////////////////////////////////////////////////// - setUp : function () { - }, + setUp: function() {}, -//////////////////////////////////////////////////////////////////////////////// -/// @brief tear down -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief tear down + //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { - }, + tearDown: function() {}, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.KEYS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.KEYS function + //////////////////////////////////////////////////////////////////////////////// - testKeys : function () { + testKeys: function() { assertEqual([ ], aql.KEYS([ ], true)); assertEqual([ 0, 1, 2 ], aql.KEYS([ 0, 1, 2 ], true)); assertEqual([ 0, 1, 2 ], aql.KEYS([ 1, 2, 3 ], true)); @@ -88,511 +86,628 @@ function ahuacatlOperatorsTestSuite () { assertEqual([ 'a1', 'a10', 'a20', 'a200', 'a21' ], aql.KEYS({ 'a200' : true, 'a21' : true, 'a20' : true, 'a10' : false, 'a1' : null }, true)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NULL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NULL function + //////////////////////////////////////////////////////////////////////////////// - testIsNullTrue : function () { - assertTrue(aql.AQL_IS_NULL(null)); + testIsNullTrue: function() { assertTrue(aql.AQL_IS_NULL(undefined)); assertTrue(aql.AQL_IS_NULL(NaN)); assertTrue(aql.AQL_IS_NULL(1.3e308 * 1.3e308)); + var values = [ null ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_NULL(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_NULL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NULL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NULL function + //////////////////////////////////////////////////////////////////////////////// - testIsNullFalse : function () { - assertFalse(aql.AQL_IS_NULL(0)); - assertFalse(aql.AQL_IS_NULL(1)); - assertFalse(aql.AQL_IS_NULL(-1)); - assertFalse(aql.AQL_IS_NULL(0.1)); - assertFalse(aql.AQL_IS_NULL(-0.1)); - assertFalse(aql.AQL_IS_NULL(false)); - assertFalse(aql.AQL_IS_NULL(true)); - assertFalse(aql.AQL_IS_NULL('abc')); - assertFalse(aql.AQL_IS_NULL('null')); - assertFalse(aql.AQL_IS_NULL('false')); - assertFalse(aql.AQL_IS_NULL('undefined')); - assertFalse(aql.AQL_IS_NULL('')); - assertFalse(aql.AQL_IS_NULL(' ')); - assertFalse(aql.AQL_IS_NULL([ ])); - assertFalse(aql.AQL_IS_NULL([ 0 ])); - assertFalse(aql.AQL_IS_NULL([ 0, 1 ])); - assertFalse(aql.AQL_IS_NULL([ 1, 2 ])); - assertFalse(aql.AQL_IS_NULL({ })); - assertFalse(aql.AQL_IS_NULL({ 'a' : 0 })); - assertFalse(aql.AQL_IS_NULL({ 'a' : 1 })); - assertFalse(aql.AQL_IS_NULL({ 'a' : 0, 'b' : 1 })); + testIsNullFalse: function() { + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_NULL(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_NULL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testIsBoolTrue : function () { - assertTrue(aql.AQL_IS_BOOL(false)); - assertTrue(aql.AQL_IS_BOOL(true)); + testIsBoolTrue: function() { + var values = [ false, true ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_BOOL(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testIsBoolFalse : function () { + testIsBoolFalse: function() { assertFalse(aql.AQL_IS_BOOL(undefined)); assertFalse(aql.AQL_IS_BOOL(NaN)); assertFalse(aql.AQL_IS_BOOL(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_BOOL(0)); - assertFalse(aql.AQL_IS_BOOL(1)); - assertFalse(aql.AQL_IS_BOOL(-1)); - assertFalse(aql.AQL_IS_BOOL(0.1)); - assertFalse(aql.AQL_IS_BOOL(-0.1)); - assertFalse(aql.AQL_IS_BOOL(null)); - assertFalse(aql.AQL_IS_BOOL('abc')); - assertFalse(aql.AQL_IS_BOOL('null')); - assertFalse(aql.AQL_IS_BOOL('false')); - assertFalse(aql.AQL_IS_BOOL('undefined')); - assertFalse(aql.AQL_IS_BOOL('')); - assertFalse(aql.AQL_IS_BOOL(' ')); - assertFalse(aql.AQL_IS_BOOL([ ])); - assertFalse(aql.AQL_IS_BOOL([ 0 ])); - assertFalse(aql.AQL_IS_BOOL([ 0, 1 ])); - assertFalse(aql.AQL_IS_BOOL([ 1, 2 ])); - assertFalse(aql.AQL_IS_BOOL([ '' ])); - assertFalse(aql.AQL_IS_BOOL([ '0' ])); - assertFalse(aql.AQL_IS_BOOL([ '1' ])); - assertFalse(aql.AQL_IS_BOOL([ true ])); - assertFalse(aql.AQL_IS_BOOL([ false ])); - assertFalse(aql.AQL_IS_BOOL({ })); - assertFalse(aql.AQL_IS_BOOL({ 'a' : 0 })); - assertFalse(aql.AQL_IS_BOOL({ 'a' : 1 })); - assertFalse(aql.AQL_IS_BOOL({ 'a' : 0, 'b' : 1 })); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_BOOL(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NUMBER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NUMBER function + //////////////////////////////////////////////////////////////////////////////// - testIsNumberTrue : function () { - assertTrue(aql.AQL_IS_NUMBER(0)); - assertTrue(aql.AQL_IS_NUMBER(1)); - assertTrue(aql.AQL_IS_NUMBER(-1)); - assertTrue(aql.AQL_IS_NUMBER(0.1)); - assertTrue(aql.AQL_IS_NUMBER(-0.1)); - assertTrue(aql.AQL_IS_NUMBER(12.5356)); - assertTrue(aql.AQL_IS_NUMBER(-235.26436)); - assertTrue(aql.AQL_IS_NUMBER(-23.3e17)); - assertTrue(aql.AQL_IS_NUMBER(563.44576e19)); + testIsNumberTrue: function() { + var values = [0, 1, -1, 0.1, 12.5356, -235.26436, -23.3e17, 563.44576e19]; + + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_NUMBER(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_NUMBER(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NUMBER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NUMBER function + //////////////////////////////////////////////////////////////////////////////// - testIsNumberFalse : function () { - assertFalse(aql.AQL_IS_NUMBER(false)); - assertFalse(aql.AQL_IS_NUMBER(true)); + testIsNumberFalse: function() { assertFalse(aql.AQL_IS_NUMBER(undefined)); assertFalse(aql.AQL_IS_NUMBER(NaN)); assertFalse(aql.AQL_IS_NUMBER(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_NUMBER(null)); - assertFalse(aql.AQL_IS_NUMBER('abc')); - assertFalse(aql.AQL_IS_NUMBER('null')); - assertFalse(aql.AQL_IS_NUMBER('false')); - assertFalse(aql.AQL_IS_NUMBER('undefined')); - assertFalse(aql.AQL_IS_NUMBER('')); - assertFalse(aql.AQL_IS_NUMBER(' ')); - assertFalse(aql.AQL_IS_NUMBER([ ])); - assertFalse(aql.AQL_IS_NUMBER([ 0 ])); - assertFalse(aql.AQL_IS_NUMBER([ 0, 1 ])); - assertFalse(aql.AQL_IS_NUMBER([ 1, 2 ])); - assertFalse(aql.AQL_IS_NUMBER([ '' ])); - assertFalse(aql.AQL_IS_NUMBER([ '0' ])); - assertFalse(aql.AQL_IS_NUMBER([ '1' ])); - assertFalse(aql.AQL_IS_NUMBER([ true ])); - assertFalse(aql.AQL_IS_NUMBER([ false ])); - assertFalse(aql.AQL_IS_NUMBER({ })); - assertFalse(aql.AQL_IS_NUMBER({ 'a' : 0 })); - assertFalse(aql.AQL_IS_NUMBER({ 'a' : 1 })); - assertFalse(aql.AQL_IS_NUMBER({ 'a' : 0, 'b' : 1 })); + + var values = [ + false, + true, + null, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_NUMBER(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_NUMBER(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_STRING function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_STRING function + //////////////////////////////////////////////////////////////////////////////// - testIsStringTrue : function () { - assertTrue(aql.AQL_IS_STRING('abc')); - assertTrue(aql.AQL_IS_STRING('null')); - assertTrue(aql.AQL_IS_STRING('false')); - assertTrue(aql.AQL_IS_STRING('undefined')); - assertTrue(aql.AQL_IS_STRING('')); - assertTrue(aql.AQL_IS_STRING(' ')); + testIsStringTrue: function() { + var values = ["'abc'", "'null'", "'false'", "'undefined'", "''", "' '"]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_STRING(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_STRING(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_STRING function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_STRING function + //////////////////////////////////////////////////////////////////////////////// - testIsStringFalse : function () { - assertFalse(aql.AQL_IS_STRING(false)); - assertFalse(aql.AQL_IS_STRING(true)); + testIsStringFalse: function() { assertFalse(aql.AQL_IS_STRING(undefined)); assertFalse(aql.AQL_IS_STRING(NaN)); assertFalse(aql.AQL_IS_STRING(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_STRING(0)); - assertFalse(aql.AQL_IS_STRING(1)); - assertFalse(aql.AQL_IS_STRING(-1)); - assertFalse(aql.AQL_IS_STRING(0.1)); - assertFalse(aql.AQL_IS_STRING(-0.1)); - assertFalse(aql.AQL_IS_STRING(null)); - assertFalse(aql.AQL_IS_STRING([ ])); - assertFalse(aql.AQL_IS_STRING([ 0 ])); - assertFalse(aql.AQL_IS_STRING([ 0, 1 ])); - assertFalse(aql.AQL_IS_STRING([ 1, 2 ])); - assertFalse(aql.AQL_IS_STRING([ '' ])); - assertFalse(aql.AQL_IS_STRING([ '0' ])); - assertFalse(aql.AQL_IS_STRING([ '1' ])); - assertFalse(aql.AQL_IS_STRING([ true ])); - assertFalse(aql.AQL_IS_STRING([ false ])); - assertFalse(aql.AQL_IS_STRING({ })); - assertFalse(aql.AQL_IS_STRING({ 'a' : 0 })); - assertFalse(aql.AQL_IS_STRING({ 'a' : 1 })); - assertFalse(aql.AQL_IS_STRING({ 'a' : 0, 'b' : 1 })); + + var values = [ + false, + true, + 0, + 1, + -1, + 0.1, + -0.1, + null, + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_STRING(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_STRING(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_LIST function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_LIST function + //////////////////////////////////////////////////////////////////////////////// - testIsListTrue : function () { - assertTrue(aql.AQL_IS_LIST([ ])); - assertTrue(aql.AQL_IS_LIST([ 0 ])); - assertTrue(aql.AQL_IS_LIST([ 0, 1 ])); - assertTrue(aql.AQL_IS_LIST([ 1, 2 ])); - assertTrue(aql.AQL_IS_LIST([ '' ])); - assertTrue(aql.AQL_IS_LIST([ '0' ])); - assertTrue(aql.AQL_IS_LIST([ '1' ])); - assertTrue(aql.AQL_IS_LIST([ true ])); - assertTrue(aql.AQL_IS_LIST([ false ])); + testIsListTrue: function() { + var values = [ + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_LIST(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_LIST(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_LIST function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_LIST function + //////////////////////////////////////////////////////////////////////////////// - testIsListFalse : function () { - assertFalse(aql.AQL_IS_LIST('abc')); - assertFalse(aql.AQL_IS_LIST('null')); - assertFalse(aql.AQL_IS_LIST('false')); - assertFalse(aql.AQL_IS_LIST('undefined')); - assertFalse(aql.AQL_IS_LIST('')); - assertFalse(aql.AQL_IS_LIST(' ')); - assertFalse(aql.AQL_IS_LIST(false)); - assertFalse(aql.AQL_IS_LIST(true)); + testIsListFalse: function() { assertFalse(aql.AQL_IS_LIST(undefined)); assertFalse(aql.AQL_IS_LIST(NaN)); assertFalse(aql.AQL_IS_LIST(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_LIST(0)); - assertFalse(aql.AQL_IS_LIST(1)); - assertFalse(aql.AQL_IS_LIST(-1)); - assertFalse(aql.AQL_IS_LIST(0.1)); - assertFalse(aql.AQL_IS_LIST(-0.1)); - assertFalse(aql.AQL_IS_LIST(null)); - assertFalse(aql.AQL_IS_LIST({ })); - assertFalse(aql.AQL_IS_LIST({ 'a' : 0 })); - assertFalse(aql.AQL_IS_LIST({ 'a' : 1 })); - assertFalse(aql.AQL_IS_LIST({ 'a' : 0, 'b' : 1 })); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_LIST(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_LIST(${v}))`).next()); + }); }, + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_ARRAY function + //////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_ARRAY function -//////////////////////////////////////////////////////////////////////////////// - - testIsArrayTrue : function () { - assertTrue(aql.AQL_IS_ARRAY([ ])); - assertTrue(aql.AQL_IS_ARRAY([ 0 ])); - assertTrue(aql.AQL_IS_ARRAY([ 0, 1 ])); - assertTrue(aql.AQL_IS_ARRAY([ 1, 2 ])); - assertTrue(aql.AQL_IS_ARRAY([ '' ])); - assertTrue(aql.AQL_IS_ARRAY([ '0' ])); - assertTrue(aql.AQL_IS_ARRAY([ '1' ])); - assertTrue(aql.AQL_IS_ARRAY([ true ])); - assertTrue(aql.AQL_IS_ARRAY([ false ])); + testIsArrayTrue: function() { + var values = [ + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_ARRAY(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_ARRAY(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_ARRAY function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_ARRAY function + //////////////////////////////////////////////////////////////////////////////// - testIsArrayFalse : function () { - assertFalse(aql.AQL_IS_ARRAY('abc')); - assertFalse(aql.AQL_IS_ARRAY('null')); - assertFalse(aql.AQL_IS_ARRAY('false')); - assertFalse(aql.AQL_IS_ARRAY('undefined')); - assertFalse(aql.AQL_IS_ARRAY('')); - assertFalse(aql.AQL_IS_ARRAY(' ')); - assertFalse(aql.AQL_IS_ARRAY(false)); - assertFalse(aql.AQL_IS_ARRAY(true)); + testIsArrayFalse: function() { assertFalse(aql.AQL_IS_ARRAY(undefined)); assertFalse(aql.AQL_IS_ARRAY(NaN)); assertFalse(aql.AQL_IS_ARRAY(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_ARRAY(0)); - assertFalse(aql.AQL_IS_ARRAY(1)); - assertFalse(aql.AQL_IS_ARRAY(-1)); - assertFalse(aql.AQL_IS_ARRAY(0.1)); - assertFalse(aql.AQL_IS_ARRAY(-0.1)); - assertFalse(aql.AQL_IS_ARRAY(null)); - assertFalse(aql.AQL_IS_ARRAY({ })); - assertFalse(aql.AQL_IS_ARRAY({ 'a' : 0 })); - assertFalse(aql.AQL_IS_ARRAY({ 'a' : 1 })); - assertFalse(aql.AQL_IS_ARRAY({ 'a' : 0, 'b' : 1 })); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_ARRAY(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_ARRAY(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_DOCUMENT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_DOCUMENT function + //////////////////////////////////////////////////////////////////////////////// - testIsDocumentTrue : function () { - assertTrue(aql.AQL_IS_DOCUMENT({ })); - assertTrue(aql.AQL_IS_DOCUMENT({ 'a' : 0 })); - assertTrue(aql.AQL_IS_DOCUMENT({ 'a' : 1 })); - assertTrue(aql.AQL_IS_DOCUMENT({ 'a' : 0, 'b' : 1 })); - assertTrue(aql.AQL_IS_DOCUMENT({ '1' : false, 'b' : false })); - assertTrue(aql.AQL_IS_DOCUMENT({ '0' : false })); + testIsDocumentTrue: function() { + var values = [ + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' : 1 }", + "{ '1' : false, 'b' : false }", + "{ '0' : false }", + ]; + values.forEach(function(v) { + assertTrue(db._query(`RETURN IS_DOCUMENT(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_DOCUMENT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_DOCUMENT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_DOCUMENT function + //////////////////////////////////////////////////////////////////////////////// - testIsDocumentFalse : function () { - assertFalse(aql.AQL_IS_DOCUMENT('abc')); - assertFalse(aql.AQL_IS_DOCUMENT('null')); - assertFalse(aql.AQL_IS_DOCUMENT('false')); - assertFalse(aql.AQL_IS_DOCUMENT('undefined')); - assertFalse(aql.AQL_IS_DOCUMENT('')); - assertFalse(aql.AQL_IS_DOCUMENT(' ')); - assertFalse(aql.AQL_IS_DOCUMENT(false)); - assertFalse(aql.AQL_IS_DOCUMENT(true)); + testIsDocumentFalse: function() { assertFalse(aql.AQL_IS_DOCUMENT(undefined)); assertFalse(aql.AQL_IS_DOCUMENT(NaN)); assertFalse(aql.AQL_IS_DOCUMENT(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_DOCUMENT(0)); - assertFalse(aql.AQL_IS_DOCUMENT(1)); - assertFalse(aql.AQL_IS_DOCUMENT(-1)); - assertFalse(aql.AQL_IS_DOCUMENT(0.1)); - assertFalse(aql.AQL_IS_DOCUMENT(-0.1)); - assertFalse(aql.AQL_IS_DOCUMENT(null)); - assertFalse(aql.AQL_IS_DOCUMENT([ ])); - assertFalse(aql.AQL_IS_DOCUMENT([ 0 ])); - assertFalse(aql.AQL_IS_DOCUMENT([ 0, 1 ])); - assertFalse(aql.AQL_IS_DOCUMENT([ 1, 2 ])); - assertFalse(aql.AQL_IS_DOCUMENT([ '' ])); - assertFalse(aql.AQL_IS_DOCUMENT([ '0' ])); - assertFalse(aql.AQL_IS_DOCUMENT([ '1' ])); - assertFalse(aql.AQL_IS_DOCUMENT([ true ])); - assertFalse(aql.AQL_IS_DOCUMENT([ false ])); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function(v) { + assertFalse(db._query(`RETURN IS_DOCUMENT(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_DOCUMENT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_OBJECT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_OBJECT function + //////////////////////////////////////////////////////////////////////////////// - testIsObjectTrue : function () { - assertTrue(aql.AQL_IS_OBJECT({ })); - assertTrue(aql.AQL_IS_OBJECT({ 'a' : 0 })); - assertTrue(aql.AQL_IS_OBJECT({ 'a' : 1 })); - assertTrue(aql.AQL_IS_OBJECT({ 'a' : 0, 'b' : 1 })); - assertTrue(aql.AQL_IS_OBJECT({ '1' : false, 'b' : false })); - assertTrue(aql.AQL_IS_OBJECT({ '0' : false })); + testIsObjectTrue: function() { + var values = [ + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' : 1 }", + "{ '1' : false, 'b' : false }", + "{ '0' : false }", + ]; + values.forEach(function(v) { + assertTrue(db._query(`RETURN IS_OBJECT(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_OBJECT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_OBJECT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_OBJECT function + //////////////////////////////////////////////////////////////////////////////// - testIsObjectFalse : function () { - assertFalse(aql.AQL_IS_OBJECT('abc')); - assertFalse(aql.AQL_IS_OBJECT('null')); - assertFalse(aql.AQL_IS_OBJECT('false')); - assertFalse(aql.AQL_IS_OBJECT('undefined')); - assertFalse(aql.AQL_IS_OBJECT('')); - assertFalse(aql.AQL_IS_OBJECT(' ')); - assertFalse(aql.AQL_IS_OBJECT(false)); - assertFalse(aql.AQL_IS_OBJECT(true)); + testIsObjecttFalse: function() { assertFalse(aql.AQL_IS_OBJECT(undefined)); assertFalse(aql.AQL_IS_OBJECT(NaN)); assertFalse(aql.AQL_IS_OBJECT(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_OBJECT(0)); - assertFalse(aql.AQL_IS_OBJECT(1)); - assertFalse(aql.AQL_IS_OBJECT(-1)); - assertFalse(aql.AQL_IS_OBJECT(0.1)); - assertFalse(aql.AQL_IS_OBJECT(-0.1)); - assertFalse(aql.AQL_IS_OBJECT(null)); - assertFalse(aql.AQL_IS_OBJECT([ ])); - assertFalse(aql.AQL_IS_OBJECT([ 0 ])); - assertFalse(aql.AQL_IS_OBJECT([ 0, 1 ])); - assertFalse(aql.AQL_IS_OBJECT([ 1, 2 ])); - assertFalse(aql.AQL_IS_OBJECT([ '' ])); - assertFalse(aql.AQL_IS_OBJECT([ '0' ])); - assertFalse(aql.AQL_IS_OBJECT([ '1' ])); - assertFalse(aql.AQL_IS_OBJECT([ true ])); - assertFalse(aql.AQL_IS_OBJECT([ false ])); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function(v) { + assertFalse(db._query(`RETURN IS_OBJECT(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_OBJECT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testCastBoolTrue : function () { - assertEqual(true, aql.AQL_TO_BOOL(true)); - assertEqual(true, aql.AQL_TO_BOOL(1)); - assertEqual(true, aql.AQL_TO_BOOL(2)); - assertEqual(true, aql.AQL_TO_BOOL(-1)); - assertEqual(true, aql.AQL_TO_BOOL(100)); - assertEqual(true, aql.AQL_TO_BOOL(100.01)); - assertEqual(true, aql.AQL_TO_BOOL(0.001)); - assertEqual(true, aql.AQL_TO_BOOL(-0.001)); - assertEqual(true, aql.AQL_TO_BOOL(' ')); - assertEqual(true, aql.AQL_TO_BOOL(' ')); - assertEqual(true, aql.AQL_TO_BOOL('1')); - assertEqual(true, aql.AQL_TO_BOOL('1 ')); - assertEqual(true, aql.AQL_TO_BOOL('0')); - assertEqual(true, aql.AQL_TO_BOOL('-1')); - assertEqual(true, aql.AQL_TO_BOOL([ 0 ])); - assertEqual(true, aql.AQL_TO_BOOL([ 0, 1 ])); - assertEqual(true, aql.AQL_TO_BOOL([ 1, 2 ])); - assertEqual(true, aql.AQL_TO_BOOL([ -1, 0 ])); - assertEqual(true, aql.AQL_TO_BOOL([ '' ])); - assertEqual(true, aql.AQL_TO_BOOL([ false ])); - assertEqual(true, aql.AQL_TO_BOOL([ true ])); - assertEqual(true, aql.AQL_TO_BOOL({ 'a' : true })); - assertEqual(true, aql.AQL_TO_BOOL({ 'a' : false })); - assertEqual(true, aql.AQL_TO_BOOL({ 'a' : false, 'b' : 0 })); - assertEqual(true, aql.AQL_TO_BOOL({ '0' : false })); - assertEqual(true, aql.AQL_TO_BOOL([ ])); - assertEqual(true, aql.AQL_TO_BOOL({ })); + testCastBoolTrue: function() { + var values = [ + 1, + 2, + -1, + 100, + 100.01, + 0.001, + -0.001, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '" "', + '" "', + '"1"', + '"1 "', + '"0"', + '"-1"', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ -1, 0 ]", + "[ '' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : true }", + "{ 'a' : false }", + "{ 'a' : false, 'b' : 0 }", + "{ '0' : false }" + ]; + values.forEach(function(v) { + assertEqual(true, db._query(`RETURN TO_BOOL(${v})`).next()); + assertEqual(true, db._query(`RETURN NOOPT(TO_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testCastBoolFalse : function () { - assertEqual(false, aql.AQL_TO_BOOL(0)); + testCastBoolFalse: function() { assertEqual(false, aql.AQL_TO_BOOL(NaN)); - assertEqual(false, aql.AQL_TO_BOOL('')); assertEqual(false, aql.AQL_TO_BOOL(undefined)); - assertEqual(false, aql.AQL_TO_BOOL(null)); - assertEqual(false, aql.AQL_TO_BOOL(false)); + + var values = [0, "''", null, false]; + values.forEach(function(v) { + assertEqual(false, db._query(`RETURN TO_BOOL(${v})`).next()); + assertEqual(false, db._query(`RETURN NOOPT(TO_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_NUMBER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_NUMBER function + //////////////////////////////////////////////////////////////////////////////// - testCastNumber : function () { + testCastNumber: function() { assertEqual(null, aql.AQL_TO_NUMBER(undefined)); - assertEqual(0, aql.AQL_TO_NUMBER(null)); - assertEqual(0, aql.AQL_TO_NUMBER(false)); - assertEqual(1, aql.AQL_TO_NUMBER(true)); - assertEqual(1, aql.AQL_TO_NUMBER(1)); - assertEqual(2, aql.AQL_TO_NUMBER(2)); - assertEqual(-1, aql.AQL_TO_NUMBER(-1)); - assertEqual(0, aql.AQL_TO_NUMBER(0)); assertEqual(null, aql.AQL_TO_NUMBER(NaN)); - assertEqual(0, aql.AQL_TO_NUMBER('')); - assertEqual(0, aql.AQL_TO_NUMBER(' ')); - assertEqual(0, aql.AQL_TO_NUMBER(' ')); - assertEqual(1, aql.AQL_TO_NUMBER('1')); - assertEqual(1, aql.AQL_TO_NUMBER('1 ')); - assertEqual(0, aql.AQL_TO_NUMBER('0')); - assertEqual(-1, aql.AQL_TO_NUMBER('-1')); - assertEqual(-1, aql.AQL_TO_NUMBER('-1 ')); - assertEqual(-1, aql.AQL_TO_NUMBER(' -1 ')); - assertEqual(null, aql.AQL_TO_NUMBER(' -1a')); - assertEqual(null, aql.AQL_TO_NUMBER(' 1a')); - assertEqual(null, aql.AQL_TO_NUMBER(' 12335.3 a')); - assertEqual(null, aql.AQL_TO_NUMBER('a1bc')); - assertEqual(null, aql.AQL_TO_NUMBER('aaaa1')); - assertEqual(null, aql.AQL_TO_NUMBER('-a1')); - assertEqual(-1.255, aql.AQL_TO_NUMBER('-1.255')); - assertEqual(-1.23456, aql.AQL_TO_NUMBER('-1.23456')); - assertEqual(-1.23456, aql.AQL_TO_NUMBER('-1.23456 ')); - assertEqual(1.23456, aql.AQL_TO_NUMBER(' 1.23456 ')); - assertEqual(null, aql.AQL_TO_NUMBER(' 1.23456a')); - assertEqual(null, aql.AQL_TO_NUMBER('--1')); - assertEqual(1, aql.AQL_TO_NUMBER('+1')); - assertEqual(12.42e32, aql.AQL_TO_NUMBER('12.42e32')); - assertEqual(0, aql.AQL_TO_NUMBER([ ])); - assertEqual(0, aql.AQL_TO_NUMBER([ 0 ])); - assertEqual(-17, aql.AQL_TO_NUMBER([ -17 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 0, 1 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 1, 2 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ -1, 0 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 0, 1, [ 1, 2 ], [ [ 9, 4 ] ] ])); - assertEqual(null, aql.AQL_TO_NUMBER([ { } ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 0, 1, { } ])); - assertEqual(null, aql.AQL_TO_NUMBER([ { }, { } ])); - assertEqual(0, aql.AQL_TO_NUMBER([ '' ])); - assertEqual(0, aql.AQL_TO_NUMBER([ false ])); - assertEqual(1, aql.AQL_TO_NUMBER([ true ])); - assertEqual(null, aql.AQL_TO_NUMBER({ })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : true })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : true, 'b' : 0 })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : { }, 'b' : { } })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : [ ], 'b' : [ ] })); + + var values = [ + {ex: 0, val: null}, + {ex: 0, val: false}, + {ex: 1, val: true}, + {ex: 1, val: 1}, + {ex: 2, val: 2}, + {ex: -1, val: -1}, + {ex: 0, val: 0}, + {ex: 0, val: "''"}, + {ex: 0, val: "' '"}, + {ex: 0, val: "' '"}, + {ex: 1, val: "'1'"}, + {ex: 1, val: "'1 '"}, + {ex: 1, val: "' 1 '"}, + {ex: 0, val: "'0'"}, + {ex: -1, val: "'-1'"}, + {ex: -1, val: "'-1 '"}, + {ex: -1, val: "' -1 '"}, + {ex: null, val: "' -1a '"}, + {ex: null, val: "' 1a '"}, + {ex: null, val: "' 12335.3 a '"}, + {ex: null, val: "'a1bc'"}, + {ex: null, val: "'aaa1'"}, + {ex: null, val: "'-a1'"}, + {ex: -1.255, val: "'-1.255'"}, + {ex: -1.23456, val: "'-1.23456'"}, + {ex: -1.23456, val: "'-1.23456 '"}, + {ex: 1.23456, val: "' 1.23456 '"}, + {ex: null, val: "' 1.23456a'"}, + {ex: null, val: "'--1'"}, + {ex: 1, val: "'+1'"}, + {ex: 12.42e32, val: "'12.42e32'"}, + {ex: 0, val: "[]"}, + {ex: 0, val: "[ 0 ]"}, + {ex: -17, val: "[ -17 ]"}, + {ex: null, val: "[ 0, 1 ]"}, + {ex: null, val: "[ 1, 2 ]"}, + {ex: null, val: "[ -1, 0 ]"}, + {ex: null, val: "[ 0, 1, [ 1, 2 ], [ [ 9, 4 ] ] ]"}, + {ex: null, val: "[ { } ]"}, + {ex: null, val: "[ 0, 1, { } ]"}, + {ex: null, val: "[ { }, { } ]"}, + {ex: 0, val: "[ '' ]"}, + {ex: 0, val: "[ false ]"}, + {ex: 1, val: "[ true ]"}, + {ex: null, val: "{ }"}, + {ex: null, val: "{ 'a' : true }"}, + {ex: null, val: "{ 'a' : true, 'b' : 0 }"}, + {ex: null, val: "{ 'a' : { }, 'b' : { } }"}, + {ex: null, val: "{ 'a' : [ ], 'b' : [ ] }"} + ]; + values.forEach(function(v) { + // double precission check for e=0.0001 + var q = `RETURN TO_NUMBER(${v.val})`; + var diff = db._query(q).next() - v.ex; + assertTrue(diff < 0.0001, q); + q = `RETURN NOOPT(TO_NUMBER(${v.val}))`; + diff = db._query(q).next() - v.ex; + assertTrue(diff < 0.0001, q); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_STRING function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_STRING function + //////////////////////////////////////////////////////////////////////////////// - testCastString : function () { + testCastString: function() { assertEqual('null', aql.AQL_TO_STRING(undefined)); - assertEqual('null', aql.AQL_TO_STRING(null)); - assertEqual('false', aql.AQL_TO_STRING(false)); - assertEqual('true', aql.AQL_TO_STRING(true)); - assertEqual('1', aql.AQL_TO_STRING(1)); - assertEqual('2', aql.AQL_TO_STRING(2)); - assertEqual('-1', aql.AQL_TO_STRING(-1)); - assertEqual('0', aql.AQL_TO_STRING(0)); assertEqual('null', aql.AQL_TO_STRING(NaN)); - assertEqual('', aql.AQL_TO_STRING('')); - assertEqual(' ', aql.AQL_TO_STRING(' ')); - assertEqual(' ', aql.AQL_TO_STRING(' ')); - assertEqual('1', aql.AQL_TO_STRING('1')); - assertEqual('1 ', aql.AQL_TO_STRING('1 ')); - assertEqual('0', aql.AQL_TO_STRING('0')); - assertEqual('-1', aql.AQL_TO_STRING('-1')); - assertEqual('', aql.AQL_TO_STRING([ ])); - assertEqual('0', aql.AQL_TO_STRING([ 0 ])); - assertEqual('0,1', aql.AQL_TO_STRING([ 0, 1 ])); - assertEqual('1,2', aql.AQL_TO_STRING([ 1, 2 ])); - assertEqual('-1,0', aql.AQL_TO_STRING([ -1, 0 ])); - assertEqual('0,1,1,2,9,4', aql.AQL_TO_STRING([ 0, 1, [ 1, 2 ], [ [ 9, 4 ] ] ])); - assertEqual('[object Object]', aql.AQL_TO_STRING([ { } ])); - assertEqual('0,1,[object Object]', aql.AQL_TO_STRING([ 0, 1, { } ])); - assertEqual('[object Object],[object Object]', aql.AQL_TO_STRING([ { }, { } ])); - assertEqual('', aql.AQL_TO_STRING([ '' ])); - assertEqual('false', aql.AQL_TO_STRING([ false ])); - assertEqual('true', aql.AQL_TO_STRING([ true ])); - assertEqual('[object Object]', aql.AQL_TO_STRING({ })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : true })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : true, 'b' : 0 })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : { }, 'b' : { } })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : [ ], 'b' : [ ] })); + var values = [ + {ex: "null", val: null}, + {ex: "false", val: false}, + {ex: "true", val: true}, + {ex: "1", val: 1}, + {ex: "2", val: 2}, + {ex: "-1", val: -1}, + {ex: "0", val: 0}, + {ex: "", val: "''"}, + {ex: " ", val: "' '"}, + {ex: " ", val: "' '"}, + {ex: "1", val: "'1'"}, + {ex: "1 ", val: "'1 '"}, + {ex: "0", val: "'0'"}, + {ex: "-1", val: "'-1'"}, + {ex: "", val: "[ ]"}, + {ex: "0", val: "[ 0 ]"}, + {ex: "0,1", val: "[ 0, 1 ]"}, + {ex: "1,2", val: "[ 1, 2 ]"}, + {ex: "-1,0", val: "[ -1, 0 ]"}, + {ex: "0,1,1,2,9,4", val: "[ 0, 1, [1, 2], [ [ 9, 4 ] ] ]"}, + {ex: "[object Object]", val: "[ { } ]"}, + {ex: "0,1,[object Object]", val: "[ 0, 1, { } ]"}, + {ex: "[object Object],[object Object]", val: "[ { }, { } ]"}, + {ex: "", val: "['']"}, + {ex: "false", val: "[ false ]"}, + {ex: "true", val: "[ true ]"}, + {ex: "[object Object]", val: "{ }"}, + {ex: "[object Object]", val: "{ 'a' : true }"}, + {ex: "[object Object]", val: "{ 'a' : true, 'b' : 0 }"}, + {ex: "[object Object]", val: "{ 'a' : { }, 'b' : { } }"}, + {ex: "[object Object]", val: "{ 'a' : [ ], 'b' : [ ] }"} + ]; + values.forEach(function(v) { + var q = `RETURN TO_STRING(${v.val})`; + assertEqual(v.ex, db._query(q).next(), q); + q = `RETURN NOOPT(TO_STRING(${v.val}))`; + assertEqual(v.ex, db._query(q).next(), q); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_AND function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_AND function + //////////////////////////////////////////////////////////////////////////////// - testLogicalAndUndefined : function () { + testLogicalAndUndefined: function() { var LOGICAL_AND = function (a, b) { return aql.LOGICAL_AND(function () { return a; }, function () { return b; }); }; @@ -727,22 +842,22 @@ function ahuacatlOperatorsTestSuite () { assertEqual(NaN, LOGICAL_AND('0', NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_AND function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_AND function + //////////////////////////////////////////////////////////////////////////////// - testLogicalAndBool : function () { + testLogicalAndBool: function() { assertTrue(aql.LOGICAL_AND(function () { return true; }, function () { return true; })); assertFalse(aql.LOGICAL_AND(function () { return true; }, function () { return false; })); assertFalse(aql.LOGICAL_AND(function () { return false; }, function () { return true; })); assertFalse(aql.LOGICAL_AND(function () { return false; }, function () { return false; })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_OR function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_OR function + //////////////////////////////////////////////////////////////////////////////// - testLogicalOrUndefined : function () { + testLogicalOrUndefined: function() { var LOGICAL_OR = function (a, b) { return aql.LOGICAL_OR(function () { return a; }, function () { return b; }); }; @@ -877,22 +992,22 @@ function ahuacatlOperatorsTestSuite () { assertEqual('0', LOGICAL_OR('0', NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_OR function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_OR function + //////////////////////////////////////////////////////////////////////////////// - testLogicalOrBool : function () { + testLogicalOrBool: function() { assertTrue(aql.LOGICAL_OR(function () { return true; }, function () { return true; })); assertTrue(aql.LOGICAL_OR(function () { return true; }, function () { return false; })); assertTrue(aql.LOGICAL_OR(function () { return false; }, function () { return true; })); assertFalse(aql.LOGICAL_OR(function () { return false; }, function () { return false; })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_NOT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_NOT function + //////////////////////////////////////////////////////////////////////////////// - testLogicalNotUndefined : function () { + testLogicalNotUndefined: function() { assertEqual(true, aql.LOGICAL_NOT(undefined)); assertEqual(true, aql.LOGICAL_NOT(null)); assertEqual(true, aql.LOGICAL_NOT(false)); @@ -914,11 +1029,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(true, aql.LOGICAL_NOT(NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_NOT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_NOT function + //////////////////////////////////////////////////////////////////////////////// - testLogicalNotBool : function () { + testLogicalNotBool: function() { assertTrue(aql.LOGICAL_NOT(false)); assertFalse(aql.LOGICAL_NOT(true)); @@ -926,11 +1041,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.LOGICAL_NOT(aql.LOGICAL_NOT(false))); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_EQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_EQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalEqualTrue : function () { + testRelationalEqualTrue: function() { assertTrue(aql.RELATIONAL_EQUAL(undefined, undefined)); assertTrue(aql.RELATIONAL_EQUAL(undefined, null)); assertTrue(aql.RELATIONAL_EQUAL(null, undefined)); @@ -985,11 +1100,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_EQUAL({ 'f' : { 'c' : { 'd' : [ 0, 1 ], 'a' : [ 1, 9 ] }, 'a' : false }, 'a' : true }, { 'a' : true, 'f' : { 'a' : false, 'c' : { 'a' : [ 1, 9 ], 'd' : [ 0, 1 ] } } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_EQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_EQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalEqualFalse : function () { + testRelationalEqualFalse: function() { assertFalse(aql.RELATIONAL_EQUAL(undefined, true)); assertFalse(aql.RELATIONAL_EQUAL(undefined, false)); assertFalse(aql.RELATIONAL_EQUAL(undefined, 0.0)); @@ -1128,11 +1243,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_EQUAL({ 'a' : true, 'b' : { 'a' : false, 'b' : true } }, { 'a' : true, 'b' : { 'a' : true, 'b': true } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_UNEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_UNEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalUnequalTrue : function () { + testRelationalUnequalTrue: function() { assertTrue(aql.RELATIONAL_UNEQUAL(undefined, true)); assertTrue(aql.RELATIONAL_UNEQUAL(undefined, false)); assertTrue(aql.RELATIONAL_UNEQUAL(undefined, 0.0)); @@ -1279,11 +1394,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_UNEQUAL({ 'a' : true, 'b' : { 'a' : false, 'b' : true } }, { 'a' : true, 'b' : { 'a' : true, 'b': true } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_UNEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_UNEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalUnequalFalse : function () { + testRelationalUnequalFalse: function() { assertFalse(aql.RELATIONAL_UNEQUAL(1, 1)); assertFalse(aql.RELATIONAL_UNEQUAL(0, 0)); assertFalse(aql.RELATIONAL_UNEQUAL(-1, -1)); @@ -1336,11 +1451,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_UNEQUAL({ 'f' : { 'c' : { 'd' : [ 0, 1 ], 'a' : [ 1, 9 ] }, 'a' : false }, 'a' : true }, { 'a' : true, 'f' : { 'a' : false, 'c' : { 'a' : [ 1, 9 ], 'd' : [ 0, 1 ] } } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESS function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessTrue : function () { + testRelationalLessTrue: function() { assertTrue(aql.RELATIONAL_LESS(NaN, false)); assertTrue(aql.RELATIONAL_LESS(NaN, true)); assertTrue(aql.RELATIONAL_LESS(NaN, '')); @@ -1564,11 +1679,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_LESS({ 'a' : [ 10 ], 'b' : true }, { 'a' : [ 10, 1 ] })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESS function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessFalse : function () { + testRelationalLessFalse: function() { assertFalse(aql.RELATIONAL_LESS(undefined, undefined)); assertFalse(aql.RELATIONAL_LESS(undefined, null)); assertFalse(aql.RELATIONAL_LESS(undefined, NaN)); @@ -1805,12 +1920,12 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_LESS([ 5, 6, { } ], [ 5, 6, true ])); assertFalse(aql.RELATIONAL_LESS([ 5, 6, { } ], [ 5, 6, 9, 9 ])); }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATER function -//////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterTrue : function () { + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATER function + //////////////////////////////////////////////////////////////////////////////// + + testRelationalGreaterTrue: function() { assertTrue(aql.RELATIONAL_GREATER(true, undefined)); assertTrue(aql.RELATIONAL_GREATER(false, undefined)); assertTrue(aql.RELATIONAL_GREATER(0.0, undefined)); @@ -2001,11 +2116,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_GREATER({ 'a' : [ 10, 1 ] }, { 'a' : [ 10 ], 'b' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATER function + //////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterFalse : function () { + testRelationalGreaterFalse: function() { assertFalse(aql.RELATIONAL_GREATER(undefined, undefined)); assertFalse(aql.RELATIONAL_GREATER(undefined, null)); assertFalse(aql.RELATIONAL_GREATER(null, undefined)); @@ -2217,11 +2332,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_GREATER({ 'a' : 1, 'b' : 2, 'c' : null }, { 'a' : 1, 'b' : 2 })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESSEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESSEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessEqualTrue : function () { + testRelationalLessEqualTrue: function() { assertTrue(aql.RELATIONAL_LESSEQUAL(undefined, undefined)); assertTrue(aql.RELATIONAL_LESSEQUAL(undefined, null)); assertTrue(aql.RELATIONAL_LESSEQUAL(null, undefined)); @@ -2473,11 +2588,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_LESSEQUAL({ 'a' : true, 'b' : { 'c' : 1, 'f' : 2 }, 'x' : 9 }, { 'x' : 9, 'b' : { 'f' : 2, 'c' : 1 }, 'a' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESSEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESSEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessEqualFalse : function () { + testRelationalLessEqualFalse: function() { assertFalse(aql.RELATIONAL_LESSEQUAL(true, undefined)); assertFalse(aql.RELATIONAL_LESSEQUAL(false, undefined)); assertFalse(aql.RELATIONAL_LESSEQUAL(0.0, undefined)); @@ -2658,11 +2773,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_LESSEQUAL([ null, false ], [ null, null ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATEREQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATEREQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterEqualTrue : function () { + testRelationalGreaterEqualTrue: function() { assertTrue(aql.RELATIONAL_GREATEREQUAL(undefined, undefined)); assertTrue(aql.RELATIONAL_GREATEREQUAL(undefined, null)); assertTrue(aql.RELATIONAL_GREATEREQUAL(null, undefined)); @@ -2930,11 +3045,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_GREATEREQUAL({ 'a' : true, 'b' : { 'c' : 1, 'f' : 2 }, 'x' : 9 }, { 'x' : 9, 'b' : { 'f' : 2, 'c' : 1 }, 'a' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATEREQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATEREQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterEqualFalse : function () { + testRelationalGreaterEqualFalse: function() { assertFalse(aql.RELATIONAL_GREATEREQUAL(undefined, true)); assertFalse(aql.RELATIONAL_GREATEREQUAL(undefined, false)); assertFalse(aql.RELATIONAL_GREATEREQUAL(undefined, 0.0)); @@ -3115,11 +3230,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_GREATEREQUAL([ null, null ], [ null, false ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_IN function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_IN function + //////////////////////////////////////////////////////////////////////////////// - testRelationalInUndefined : function () { + testRelationalInUndefined: function() { assertFalse(aql.RELATIONAL_IN(undefined, undefined)); assertFalse(aql.RELATIONAL_IN(undefined, null)); assertFalse(aql.RELATIONAL_IN(undefined, true)); @@ -3276,11 +3391,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_IN({ }, { 'A' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_IN function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_IN function + //////////////////////////////////////////////////////////////////////////////// - testRelationalInTrue : function () { + testRelationalInTrue: function() { assertTrue(aql.RELATIONAL_IN(null, [ null ])); assertTrue(aql.RELATIONAL_IN(null, [ null, false ])); assertTrue(aql.RELATIONAL_IN(null, [ false, null ])); @@ -3317,11 +3432,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_IN({ 'a' : { 'b' : null, 'c': 1 } }, [ 'a', 'b', { 'a' : { 'c' : 1, 'b' : null } } ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_IN function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_IN function + //////////////////////////////////////////////////////////////////////////////// - testRelationalInFalse : function () { + testRelationalInFalse: function() { assertFalse(aql.RELATIONAL_IN(undefined, [ ])); assertFalse(aql.RELATIONAL_IN(undefined, [ 0 ])); assertFalse(aql.RELATIONAL_IN(undefined, [ 0, 1 ])); @@ -3380,11 +3495,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_IN({ 'a' : true }, [ 1, 2, { 'a' : { 'a' : true } } ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testUnaryPlusUndefined : function () { + testUnaryPlusUndefined: function() { assertEqual(null, aql.UNARY_PLUS(undefined)); assertEqual(0, aql.UNARY_PLUS(null)); assertEqual(null, aql.UNARY_PLUS(NaN)); @@ -3405,11 +3520,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.UNARY_PLUS({ 'a' : 1 })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testUnaryPlusValue : function () { + testUnaryPlusValue: function() { assertEqual(0, aql.UNARY_PLUS(0)); assertEqual(1, aql.UNARY_PLUS(1)); assertEqual(-1, aql.UNARY_PLUS(-1)); @@ -3420,11 +3535,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-1054.342, aql.UNARY_PLUS(-1054.342)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_MINUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_MINUS function + //////////////////////////////////////////////////////////////////////////////// - testUnaryMinusUndefined : function () { + testUnaryMinusUndefined: function() { assertEqual(null, aql.UNARY_MINUS(undefined)); assertEqual(0, aql.UNARY_MINUS(null)); assertEqual(0, aql.UNARY_MINUS(false)); @@ -3447,11 +3562,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.UNARY_MINUS(NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_MINUS function -//////////////////////////////////////////////////////////////////////////////// - - testUnaryMinusValue : function () { + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_MINUS function + //////////////////////////////////////////////////////////////////////////////// + + testUnaryMinusValue: function() { assertEqual(0, aql.UNARY_MINUS(0)); assertEqual(1, aql.UNARY_MINUS(-1)); assertEqual(-1, aql.UNARY_MINUS(1)); @@ -3463,11 +3578,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-1054.342, aql.UNARY_MINUS(1054.342)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticPlusUndefined : function () { + testArithmeticPlusUndefined: function() { assertEqual(null, aql.ARITHMETIC_PLUS(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_PLUS(undefined, null)); assertEqual(null, aql.ARITHMETIC_PLUS(undefined, false)); @@ -3534,11 +3649,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_PLUS(1.3e308 * 10, 1.3e308 * 10)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticPlusValue : function () { + testArithmeticPlusValue: function() { assertEqual(0, aql.ARITHMETIC_PLUS(0, 0)); assertEqual(0, aql.ARITHMETIC_PLUS(1, -1)); assertEqual(0, aql.ARITHMETIC_PLUS(-1, 1)); @@ -3555,11 +3670,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(2.6e307, aql.ARITHMETIC_PLUS(1.3e307, 1.3e307)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MINUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MINUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticMinusUndefined : function () { + testArithmeticMinusUndefined: function() { assertEqual(null, aql.ARITHMETIC_MINUS(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_MINUS(undefined, null)); assertEqual(null, aql.ARITHMETIC_MINUS(undefined, false)); @@ -3623,11 +3738,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_MINUS(-1.3e308 * 10, 1.3e308 * 10)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MINUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MINUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticMinusValue : function () { + testArithmeticMinusValue: function() { assertEqual(0, aql.ARITHMETIC_MINUS(0, 0)); assertEqual(-1, aql.ARITHMETIC_MINUS(0, 1)); assertEqual(0, aql.ARITHMETIC_MINUS(-1, -1)); @@ -3648,11 +3763,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-2.6e307, aql.ARITHMETIC_MINUS(-1.3e307, 1.3e307)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_TIMES function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_TIMES function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticTimesUndefined : function () { + testArithmeticTimesUndefined: function() { assertEqual(null, aql.ARITHMETIC_TIMES(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_TIMES(undefined, null)); assertEqual(null, aql.ARITHMETIC_TIMES(undefined, false)); @@ -3721,11 +3836,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(0, aql.ARITHMETIC_TIMES('0', '0')); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_TIMES function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_TIMES function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticTimesValue : function () { + testArithmeticTimesValue: function() { assertEqual(0, aql.ARITHMETIC_TIMES(0, 0)); assertEqual(0, aql.ARITHMETIC_TIMES(1, 0)); assertEqual(0, aql.ARITHMETIC_TIMES(0, 1)); @@ -3750,11 +3865,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(1000000, aql.ARITHMETIC_TIMES(1000, 1000)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_DIVIDE function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_DIVIDE function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticDivideUndefined : function () { + testArithmeticDivideUndefined: function() { assertEqual(null, aql.ARITHMETIC_DIVIDE(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_DIVIDE(undefined, null)); assertEqual(null, aql.ARITHMETIC_DIVIDE(undefined, false)); @@ -3825,11 +3940,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_DIVIDE('0', '0')); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_DIVIDE function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_DIVIDE function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticDivideValue : function () { + testArithmeticDivideValue: function() { assertEqual(0, aql.ARITHMETIC_DIVIDE(0, 1)); assertEqual(0, aql.ARITHMETIC_DIVIDE(0, 2)); assertEqual(0, aql.ARITHMETIC_DIVIDE(0, 10)); @@ -3869,11 +3984,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(2, aql.ARITHMETIC_DIVIDE(0.22, 0.11)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MODULUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MODULUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticModulusUndefined : function () { + testArithmeticModulusUndefined: function() { assertEqual(null, aql.ARITHMETIC_MODULUS(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_MODULUS(undefined, null)); assertEqual(null, aql.ARITHMETIC_MODULUS(undefined, false)); @@ -3942,11 +4057,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_MODULUS(0, 0)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MODULUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MODULUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticModulusValue : function () { + testArithmeticModulusValue: function() { assertEqual(0, aql.ARITHMETIC_MODULUS(0, 1)); assertEqual(0, aql.ARITHMETIC_MODULUS(1, 1)); assertEqual(1, aql.ARITHMETIC_MODULUS(1, 2)); @@ -3996,11 +4111,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-1, aql.ARITHMETIC_MODULUS(-10, 3)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.CONCAT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.CONCAT function + //////////////////////////////////////////////////////////////////////////////// - testStringConcatUndefined : function () { + testStringConcatUndefined: function() { assertEqual("false", aql.AQL_CONCAT(undefined, false)); assertEqual("true", aql.AQL_CONCAT(undefined, true)); assertEqual("0", aql.AQL_CONCAT(undefined, 0)); @@ -4064,11 +4179,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual("a[object Object]", aql.AQL_CONCAT('a', { })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.CONCAT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.CONCAT function + //////////////////////////////////////////////////////////////////////////////// - testStringConcatValue : function () { + testStringConcatValue: function() { assertEqual('', aql.AQL_CONCAT()); assertEqual('', aql.AQL_CONCAT('')); assertEqual('a', aql.AQL_CONCAT('a')); @@ -4110,21 +4225,21 @@ function ahuacatlOperatorsTestSuite () { assertEqual('fux', aql.AQL_CONCAT(null, 'f', null, 'u', null, 'x', null)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TERNARY_OPERATOR function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TERNARY_OPERATOR function + //////////////////////////////////////////////////////////////////////////////// - testTernaryOperator : function () { + testTernaryOperator: function() { assertEqual(2, aql.TERNARY_OPERATOR(true, function () { return 2; }, function () { return -1; })); assertEqual(-1, aql.TERNARY_OPERATOR(false, function () { return 1; }, function () { return -1; })); assertEqual(2, aql.TERNARY_OPERATOR(0, function () { return 1; }, function () { return 2; })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test ranges -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test ranges + //////////////////////////////////////////////////////////////////////////////// - testRanges : function () { + testRanges: function() { assertEqual([ [ 1, 2, 3 ] ], AQL_EXECUTE("RETURN 1..3").json); assertEqual([ [ 0, 1, 2, 3 ] ], AQL_EXECUTE("RETURN null..3").json); assertEqual([ [ 1, 2, 3, 4, 5, 6, 7 ] ], AQL_EXECUTE("RETURN 1..3 + 4").json); diff --git a/lib/Basics/Logger.h b/lib/Basics/Logger.h index 0be2a1a7b3..fefdaf302d 100644 --- a/lib/Basics/Logger.h +++ b/lib/Basics/Logger.h @@ -512,6 +512,20 @@ class LoggerStream { return *this; } + template + LoggerStream& operator<<(std::vector const& v) { + for (auto const& i : v) + _out << i << " "; + return *this; + } + + template + LoggerStream& operator<<(std::unordered_set const& us) { + for (auto const& i : us) + _out << i; + return *this; + } + private: std::stringstream _out; size_t _topicId; diff --git a/lib/Basics/VelocyPackHelper.cpp b/lib/Basics/VelocyPackHelper.cpp index 28eca4412a..af22f298de 100644 --- a/lib/Basics/VelocyPackHelper.cpp +++ b/lib/Basics/VelocyPackHelper.cpp @@ -37,10 +37,17 @@ using VelocyPackHelper = arangodb::basics::VelocyPackHelper; -struct AttributeSorter { - bool operator()(std::string const& l, std::string const& r) const { - return TRI_compare_utf8(l.c_str(), l.size(), r.c_str(), r.size()) < 0; - } +bool VelocyPackHelper::AttributeSorter::operator()(std::string const& l, + std::string const& r) const { + return TRI_compare_utf8(l.c_str(), l.size(), r.c_str(), r.size()) < 0; +} + +size_t VelocyPackHelper::VPackHash::operator()(VPackSlice const& slice) const { + return slice.hash(); +}; + +bool VelocyPackHelper::VPackEqual::operator()(VPackSlice const& lhs, VPackSlice const& rhs) const { + return VelocyPackHelper::compare(lhs, rhs, false) == 0; }; static int TypeWeight(VPackSlice const& slice) { @@ -431,7 +438,66 @@ int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs, } } +VPackBuilder VelocyPackHelper::merge(VPackSlice const& lhs, + VPackSlice const& rhs, + bool nullMeansRemove, bool mergeObjects) { + return VPackCollection::merge(lhs, rhs, mergeObjects, nullMeansRemove); +} +double VelocyPackHelper::toDouble(VPackSlice const& slice, bool& failed) { + TRI_ASSERT(!slice.isNone()); + + failed = false; + switch (slice.type()) { + case VPackValueType::None: + case VPackValueType::Null: + return 0.0; + case VPackValueType::Bool: + return (slice.getBoolean() ? 1.0 : 0.0); + case VPackValueType::Double: + case VPackValueType::Int: + case VPackValueType::UInt: + case VPackValueType::SmallInt: + return slice.getNumericValue(); + case VPackValueType::String: + { + std::string tmp = slice.copyString(); + try { + // try converting string to number + return std::stod(tmp); + } catch (...) { + if (tmp.empty()) { + return 0.0; + } + // conversion failed + } + break; + } + case VPackValueType::Array: + { + VPackValueLength const n = slice.length(); + + if (n == 0) { + return 0.0; + } else if (n == 1) { + return VelocyPackHelper::toDouble(slice.at(0), failed); + } + break; + } + case VPackValueType::Object: + case VPackValueType::UTCDate: + case VPackValueType::External: + case VPackValueType::MinKey: + case VPackValueType::MaxKey: + case VPackValueType::Binary: + case VPackValueType::BCD: + case VPackValueType::Custom: + break; + } + + failed = true; + return 0.0; +} arangodb::LoggerStream& operator<< (arangodb::LoggerStream& logger, VPackSlice const& slice) { diff --git a/lib/Basics/VelocyPackHelper.h b/lib/Basics/VelocyPackHelper.h index d632750eba..20888264b7 100644 --- a/lib/Basics/VelocyPackHelper.h +++ b/lib/Basics/VelocyPackHelper.h @@ -38,6 +38,36 @@ class VelocyPackHelper { ~VelocyPackHelper() = delete; public: + + struct VPackHash { + size_t operator()(arangodb::velocypack::Slice const&) const; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief equality comparator for VelocyPack values +//////////////////////////////////////////////////////////////////////////////// + + struct VPackEqual { + bool operator()(arangodb::velocypack::Slice const&, + arangodb::velocypack::Slice const&) const; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief less comparator for VelocyPack values +//////////////////////////////////////////////////////////////////////////////// + + template + struct VPackLess { + inline bool operator()(arangodb::velocypack::Slice const& lhs, + arangodb::velocypack::Slice const& rhs) const { + return VelocyPackHelper::compare(lhs, rhs, useUtf8) < 0; + } + }; + + struct AttributeSorter { + bool operator()(std::string const& l, std::string const& r) const; + }; + ////////////////////////////////////////////////////////////////////////////// /// @brief returns a numeric value ////////////////////////////////////////////////////////////////////////////// @@ -125,6 +155,22 @@ class VelocyPackHelper { ////////////////////////////////////////////////////////////////////////////// static int compare(VPackSlice const&, VPackSlice const&, bool); + + + ////////////////////////////////////////////////////////////////////////////// + /// @brief Merges two VelocyPack Slices + ////////////////////////////////////////////////////////////////////////////// + + static arangodb::velocypack::Builder merge(arangodb::velocypack::Slice const&, + arangodb::velocypack::Slice const&, + bool, bool); + + ////////////////////////////////////////////////////////////////////////////// + /// @brief Transforms any VelocyPack to a double value. The second parameter + /// indicates if the transformation was successful. + ////////////////////////////////////////////////////////////////////////////// + + static double toDouble(VPackSlice const&, bool&); }; } } diff --git a/lib/Basics/voc-errors.cpp b/lib/Basics/voc-errors.cpp index f5b7c53eeb..37e254c4b5 100644 --- a/lib/Basics/voc-errors.cpp +++ b/lib/Basics/voc-errors.cpp @@ -253,31 +253,14 @@ void TRI_InitializeErrorMessages () { REG_ERROR(SIMPLE_CLIENT_COULD_NOT_READ, "could not read from server"); REG_ERROR(ERROR_MALFORMED_MANIFEST_FILE, "malformed manifest file"); REG_ERROR(ERROR_INVALID_APPLICATION_MANIFEST, "manifest file is invalid"); - REG_ERROR(ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING, "missing manifest attribute"); - REG_ERROR(ERROR_CANNOT_EXTRACT_APPLICATION_ROOT, "unable to extract app root path"); REG_ERROR(ERROR_INVALID_FOXX_OPTIONS, "invalid foxx options"); - REG_ERROR(ERROR_FAILED_TO_EXECUTE_SCRIPT, "failed to execute script"); - REG_ERROR(ERROR_SYNTAX_ERROR_IN_SCRIPT, "syntax error in script"); REG_ERROR(ERROR_INVALID_MOUNTPOINT, "mountpoint is invalid"); - REG_ERROR(ERROR_NO_FOXX_FOUND, "No foxx found at this location"); REG_ERROR(ERROR_APP_NOT_FOUND, "App not found"); REG_ERROR(ERROR_APP_NEEDS_CONFIGURATION, "App not configured"); REG_ERROR(ERROR_MODULE_NOT_FOUND, "cannot locate module"); - REG_ERROR(ERROR_MODULE_SYNTAX_ERROR, "syntax error in module"); - REG_ERROR(ERROR_MODULE_BAD_WRAPPER, "failed to wrap module"); REG_ERROR(ERROR_MODULE_FAILURE, "failed to invoke module"); - REG_ERROR(ERROR_MODULE_UNKNOWN_FILE_TYPE, "unknown file type"); - REG_ERROR(ERROR_MODULE_PATH_MUST_BE_ABSOLUTE, "path must be absolute"); - REG_ERROR(ERROR_MODULE_CAN_NOT_ESCAPE, "cannot use '..' to escape top-level-directory"); - REG_ERROR(ERROR_MODULE_DRIVE_LETTER, "drive local path is not supported"); - REG_ERROR(ERROR_MODULE_BAD_MODULE_ORIGIN, "corrupted module origin"); - REG_ERROR(ERROR_MODULE_BAD_PACKAGE_ORIGIN, "corrupted package origin"); - REG_ERROR(ERROR_MODULE_DOCUMENT_IS_EMPTY, "no content"); - REG_ERROR(ERROR_MODULE_MAIN_NOT_READABLE, "cannot read main file"); - REG_ERROR(ERROR_MODULE_MAIN_NOT_JS, "main file is not of type 'js'"); REG_ERROR(RESULT_ELEMENT_EXISTS, "element not inserted into structure, because it already exists"); REG_ERROR(RESULT_ELEMENT_NOT_FOUND, "element not found in structure"); - REG_ERROR(ERROR_APP_ALREADY_EXISTS, "newest version of app already installed"); REG_ERROR(ERROR_QUEUE_ALREADY_EXISTS, "named queue already exists"); REG_ERROR(ERROR_DISPATCHER_IS_STOPPING, "dispatcher stopped"); REG_ERROR(ERROR_QUEUE_UNKNOWN, "named queue does not exist"); diff --git a/lib/Basics/voc-errors.h b/lib/Basics/voc-errors.h index 3c94da08f4..d8abba6e5f 100644 --- a/lib/Basics/voc-errors.h +++ b/lib/Basics/voc-errors.h @@ -606,57 +606,22 @@ /// The manifest file is malformed. It is not in a valid JSON format. /// - 3001: @LIT{manifest file is invalid} /// The manifest file of this application is invalid. -/// - 3002: @LIT{missing manifest attribute} -/// The manifest file is incomplete. A required attribute is missing. -/// - 3003: @LIT{unable to extract app root path} -/// The root path of the application could not be found. /// - 3004: @LIT{invalid foxx options} /// The options used to configure the foxx are invalid. -/// - 3005: @LIT{failed to execute script} -/// The script provided contains errors. -/// - 3006: @LIT{syntax error in script} -/// contains a syntax error: /// - 3007: @LIT{mountpoint is invalid} /// mountpoint is invalid -/// - 3008: @LIT{No foxx found at this location} -/// No foxx found at this location /// - 3009: @LIT{App not found} /// No app found at this mountpoint /// - 3010: @LIT{App not configured} /// The app has to be configured before it can be used /// - 3100: @LIT{cannot locate module} /// The module path could not be resolved. -/// - 3101: @LIT{syntax error in module} -/// The module could not be parsed because of a syntax error. -/// - 3102: @LIT{failed to wrap module} -/// The module wrapper could not be generated. This may indicate a problem -/// with some of the names of the module's context variables. /// - 3103: @LIT{failed to invoke module} /// Failed to invoke the module in its context. -/// - 3110: @LIT{unknown file type} -/// The module path resolves to a file of an unknown type. -/// - 3111: @LIT{path must be absolute} -/// The module path must be absolute. -/// - 3112: @LIT{cannot use '..' to escape top-level-directory} -/// The relative module path can not escape the module's top-level directory. -/// - 3113: @LIT{drive local path is not supported} -/// The module path contains a Windows drive letter, which is not supported. -/// - 3120: @LIT{corrupted module origin} -/// The module origin is invalid. -/// - 3121: @LIT{corrupted package origin} -/// The package origin is invalid. -/// - 3125: @LIT{no content} -/// The module resolves to a document which is empty or malformed. -/// - 3130: @LIT{cannot read main file} -/// The module's main file is not readable. -/// - 3131: @LIT{main file is not of type 'js'} -/// The module's main file is not a JavaScript file. /// - 10000: @LIT{element not inserted into structure, because it already exists} /// Will be returned if the element was not insert because it already exists. /// - 10001: @LIT{element not found in structure} /// Will be returned if the element was not found in the structure. -/// - 20000: @LIT{newest version of app already installed} -/// newest version of app already installed /// - 21000: @LIT{named queue already exists} /// "Will be returned if a queue with this name already exists." /// - 21001: @LIT{dispatcher stopped} @@ -3244,26 +3209,6 @@ void TRI_InitializeErrorMessages (); #define TRI_ERROR_INVALID_APPLICATION_MANIFEST (3001) -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3002: ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING -/// -/// missing manifest attribute -/// -/// The manifest file is incomplete. A required attribute is missing. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING (3002) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3003: ERROR_CANNOT_EXTRACT_APPLICATION_ROOT -/// -/// unable to extract app root path -/// -/// The root path of the application could not be found. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_CANNOT_EXTRACT_APPLICATION_ROOT (3003) - //////////////////////////////////////////////////////////////////////////////// /// @brief 3004: ERROR_INVALID_FOXX_OPTIONS /// @@ -3274,26 +3219,6 @@ void TRI_InitializeErrorMessages (); #define TRI_ERROR_INVALID_FOXX_OPTIONS (3004) -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3005: ERROR_FAILED_TO_EXECUTE_SCRIPT -/// -/// failed to execute script -/// -/// The script provided contains errors. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_FAILED_TO_EXECUTE_SCRIPT (3005) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3006: ERROR_SYNTAX_ERROR_IN_SCRIPT -/// -/// syntax error in script -/// -/// contains a syntax error: -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_SYNTAX_ERROR_IN_SCRIPT (3006) - //////////////////////////////////////////////////////////////////////////////// /// @brief 3007: ERROR_INVALID_MOUNTPOINT /// @@ -3304,16 +3229,6 @@ void TRI_InitializeErrorMessages (); #define TRI_ERROR_INVALID_MOUNTPOINT (3007) -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3008: ERROR_NO_FOXX_FOUND -/// -/// No foxx found at this location -/// -/// No foxx found at this location -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_NO_FOXX_FOUND (3008) - //////////////////////////////////////////////////////////////////////////////// /// @brief 3009: ERROR_APP_NOT_FOUND /// @@ -3344,27 +3259,6 @@ void TRI_InitializeErrorMessages (); #define TRI_ERROR_MODULE_NOT_FOUND (3100) -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3101: ERROR_MODULE_SYNTAX_ERROR -/// -/// syntax error in module -/// -/// The module could not be parsed because of a syntax error. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_SYNTAX_ERROR (3101) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3102: ERROR_MODULE_BAD_WRAPPER -/// -/// failed to wrap module -/// -/// The module wrapper could not be generated. This may indicate a problem with -/// some of the names of the module's context variables. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_BAD_WRAPPER (3102) - //////////////////////////////////////////////////////////////////////////////// /// @brief 3103: ERROR_MODULE_FAILURE /// @@ -3375,96 +3269,6 @@ void TRI_InitializeErrorMessages (); #define TRI_ERROR_MODULE_FAILURE (3103) -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3110: ERROR_MODULE_UNKNOWN_FILE_TYPE -/// -/// unknown file type -/// -/// The module path resolves to a file of an unknown type. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_UNKNOWN_FILE_TYPE (3110) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3111: ERROR_MODULE_PATH_MUST_BE_ABSOLUTE -/// -/// path must be absolute -/// -/// The module path must be absolute. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_PATH_MUST_BE_ABSOLUTE (3111) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3112: ERROR_MODULE_CAN_NOT_ESCAPE -/// -/// cannot use '..' to escape top-level-directory -/// -/// The relative module path can not escape the module's top-level directory. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_CAN_NOT_ESCAPE (3112) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3113: ERROR_MODULE_DRIVE_LETTER -/// -/// drive local path is not supported -/// -/// The module path contains a Windows drive letter, which is not supported. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_DRIVE_LETTER (3113) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3120: ERROR_MODULE_BAD_MODULE_ORIGIN -/// -/// corrupted module origin -/// -/// The module origin is invalid. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_BAD_MODULE_ORIGIN (3120) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3121: ERROR_MODULE_BAD_PACKAGE_ORIGIN -/// -/// corrupted package origin -/// -/// The package origin is invalid. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_BAD_PACKAGE_ORIGIN (3121) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3125: ERROR_MODULE_DOCUMENT_IS_EMPTY -/// -/// no content -/// -/// The module resolves to a document which is empty or malformed. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_DOCUMENT_IS_EMPTY (3125) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3130: ERROR_MODULE_MAIN_NOT_READABLE -/// -/// cannot read main file -/// -/// The module's main file is not readable. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_MAIN_NOT_READABLE (3130) - -//////////////////////////////////////////////////////////////////////////////// -/// @brief 3131: ERROR_MODULE_MAIN_NOT_JS -/// -/// main file is not of type 'js' -/// -/// The module's main file is not a JavaScript file. -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_MODULE_MAIN_NOT_JS (3131) - //////////////////////////////////////////////////////////////////////////////// /// @brief 10000: RESULT_ELEMENT_EXISTS /// @@ -3485,16 +3289,6 @@ void TRI_InitializeErrorMessages (); #define TRI_RESULT_ELEMENT_NOT_FOUND (10001) -//////////////////////////////////////////////////////////////////////////////// -/// @brief 20000: ERROR_APP_ALREADY_EXISTS -/// -/// newest version of app already installed -/// -/// newest version of app already installed -//////////////////////////////////////////////////////////////////////////////// - -#define TRI_ERROR_APP_ALREADY_EXISTS (20000) - //////////////////////////////////////////////////////////////////////////////// /// @brief 21000: ERROR_QUEUE_ALREADY_EXISTS ///