From 80d5f691f7534f36e89c73722d2c44e8cee01bc2 Mon Sep 17 00:00:00 2001 From: Grzegorz Figiel Date: Fri, 13 Jan 2017 17:52:56 +0100 Subject: [PATCH 1/2] Fix for issue#36 - loadbalancing and failover extension implemented --- .classpath | 68 - .gitignore | 43 +- .project | 15 - .../main/asciidoc/Chapter-Introduction.adoc | 2 +- .../main/asciidoc/Chapter-Introduction.adoc~ | 48 - .../src/main/asciidoc/Chapter-JDiameter.adoc | 2 +- .../src/main/asciidoc/Chapter-JDiameter.adoc~ | 39 - .../src/main/asciidoc/Chapter-MUX.adoc~ | 44 - .../main/asciidoc/Diameter_User_Guide.adoc~ | 43 - .../Section-Introduction-Message_Format.adoc~ | 86 - .../Section-JDiameter-Configuration.adoc | 214 +- .../Section-JDiameter-Configuration.adoc~ | 498 - .../asciidoc/Section-JDiameter-Setup.adoc~ | 69 - .../Section-JDiameter-Source_Overview.adoc~ | 313 - ...on-JDiameter-Validator-Configuration.adoc~ | 263 - ...-JDiameter-Validator-Source_Overview.adoc~ | 63 - .../Section-JDiameter-Validator.adoc~ | 36 - .../src/main/asciidoc/Section-MUX-Setup.adoc | 16 +- .../src/main/asciidoc/Section-MUX-Setup.adoc~ | 68 - .../Section-MUX-Source_Overview.adoc~ | 90 - .../src/main/asciidoc/js/default.js~ | 6554 ----- .../main/asciidoc/stylesheets/telestax.css~ | 22471 ---------------- .../ro/ClientRoSessionDataReplicatedImpl.java | 19 + core/jdiameter/api/.gitignore | 11 + .../java/org/jdiameter/api/Configuration.java | 10 + .../jdiameter/api/MutableConfiguration.java | 7 + .../api/NoMorePeersAvailableException.java | 101 + .../java/org/jdiameter/api/RequestType.java | 59 + .../api/SessionPersistenceStorage.java | 41 + .../main/java/org/jdiameter/api/Stack.java | 7 + .../api/ro/ClientRoSessionListener.java | 31 + .../org/jdiameter/client/api/IContainer.java | 21 +- .../org/jdiameter/client/api/IMessage.java | 37 +- .../client/api/controller/IPeerTable.java | 21 +- .../jdiameter/client/api/router/IRouter.java | 10 +- .../org/jdiameter/client/impl/StackImpl.java | 38 +- .../impl/app/cca/ClientCCASessionImpl.java | 336 +- .../app/ro/ClientRoSessionDataLocalImpl.java | 18 +- .../impl/app/ro/ClientRoSessionImpl.java | 635 +- .../jdiameter/client/impl/app/ro/Event.java | 2 +- .../impl/app/ro/IClientRoSessionData.java | 8 +- .../client/impl/controller/PeerImpl.java | 4 +- .../impl/helpers/EmptyConfiguration.java | 16 +- .../client/impl/helpers/Parameters.java | 24 + .../client/impl/helpers/XMLConfiguration.java | 262 +- .../client/impl/parser/MessageImpl.java | 24 + .../impl/router/FailureAwareRouter.java | 228 + .../client/impl/router/RouterImpl.java | 347 +- .../impl/router/WeightedRoundRobinRouter.java | 30 +- .../transport/tcp/TCPClientConnection.java | 9 + .../data/IRoutingAwareSessionDatasource.java | 58 + .../impl/app/AppRoutingAwareSessionImpl.java | 165 + .../impl/app/cca/AppCCASessionImpl.java | 9 +- .../impl/app/cca/CCASessionFactoryImpl.java | 6 +- .../common/impl/app/ro/AppRoSessionImpl.java | 9 +- .../impl/app/ro/RoSessionFactoryImpl.java | 24 +- .../common/impl/data/LocalDataSource.java | 41 +- .../impl/data/RoutingAwareDataSource.java | 157 + .../server/impl/FailureAwareRouter.java | 22 + .../org/jdiameter/server/impl/PeerImpl.java | 21 +- .../impl/app/cca/ServerCCASessionImpl.java | 2 +- .../impl/app/ro/ServerRoSessionImpl.java | 2 +- .../server/impl/fsm/PeerFSMImpl.java | 22 +- .../impl/helpers/EmptyConfiguration.java | 33 +- .../server/impl/helpers/XMLConfiguration.java | 292 +- .../resources/META-INF/jdiameter-client.xsd | 32 + .../resources/META-INF/jdiameter-server.xsd | 32 + ...nfig.xml => jdiameter-config_baseline.xml} | 0 .../jdiameter-config_ext_routing_failover.xml | 102 + .../stack/DiameterStackMultiplexer.java | 132 +- .../stack/DiameterStackMultiplexerMBean.java | 56 +- .../diameter/stack/DiameterStackProxy.java | 17 +- .../diameter/stack/management/Parameters.java | 8 + .../stack/management/ParametersImpl.java | 61 +- core/mux/pom.xml | 8 + core/mux/sar-jboss-4/pom.xml | 17 +- core/mux/sar-jboss-5/pom.xml | 13 +- core/mux/sar-jboss-7/pom.xml | 2 + 78 files changed, 2856 insertions(+), 31888 deletions(-) delete mode 100644 .classpath delete mode 100644 .project delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Chapter-MUX.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Diameter_User_Guide.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-Introduction-Message_Format.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Setup.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Source_Overview.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Configuration.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Source_Overview.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Source_Overview.adoc~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/js/default.js~ delete mode 100644 core/docs/sources-asciidoc/src/main/asciidoc/stylesheets/telestax.css~ create mode 100644 core/jdiameter/api/.gitignore create mode 100644 core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java create mode 100644 core/jdiameter/api/src/main/java/org/jdiameter/api/RequestType.java create mode 100644 core/jdiameter/api/src/main/java/org/jdiameter/api/SessionPersistenceStorage.java create mode 100644 core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java create mode 100644 core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java create mode 100644 core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java create mode 100644 core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java create mode 100644 core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/FailureAwareRouter.java rename core/mux/common/config/{jdiameter-config.xml => jdiameter-config_baseline.xml} (100%) create mode 100644 core/mux/common/config/jdiameter-config_ext_routing_failover.xml diff --git a/.classpath b/.classpath deleted file mode 100644 index 8dd6774dd..000000000 --- a/.classpath +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.gitignore b/.gitignore index cdfed9175..c57e92307 100644 --- a/.gitignore +++ b/.gitignore @@ -1,30 +1,47 @@ -# Java compiled # -################# +######## Java compiled ######### +################################ *.class -# Eclipse # -########### +########### Eclipse ############ +################################ .classpath .project .settings -# IntelliJ IDEA # -################# -.idea/ +######## IntelliJ IDEA ######### +################################ +.idea *.iml *.iws -# Maven # -######### +########## NetBeans ############ +################################ +nbactions.xml + +# Mobile Tools for Java (J2ME) # +################################ +.mtj.tmp + +############ Maven ############# +################################ target +*.jar +*.war +*.ear -# OS generated files # -###################### +###### OS generated files ###### +################################ +.directory +.Trashes +._* +*~ .DS_Store .DS_Store? -._* .Spotlight-V100 -.Trashes Icon? ehthumbs.db Thumbs.db + +######## VM crash logs ######### +################################ +hs_err_pid* diff --git a/.project b/.project deleted file mode 100644 index 005102c45..000000000 --- a/.project +++ /dev/null @@ -1,15 +0,0 @@ - - - diameter-parent - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.jdt.core.javanature - - \ No newline at end of file diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc b/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc index 1061ed188..8f09f1b60 100644 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc +++ b/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc @@ -1,7 +1,7 @@ [[_introduction]] = Introduction to {this-platform} Diameter -Diameter is a computer networking protocol for Authentication, Authorization and Accounting (), as defined in RFC3588. +Diameter is a computer networking protocol for Authentication, Authorization and Accounting (AAA), as defined in RFC3588. It is a successor to RADIUS, and has been designed to overcome certain RADIUS limitations: * No transport reliability and flexibility (Diameter uses TCP/SCTP instead of UDP). diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc~ deleted file mode 100644 index b8ed78f0d..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc~ +++ /dev/null @@ -1,48 +0,0 @@ -[[_introduction]] -= Introduction to &THIS.PLATFORM; Diameter - -Diameter is a computer networking protocol for Authentication, Authorization and Accounting (), as defined in RFC3588. -It is a successor to RADIUS, and has been designed to overcome certain RADIUS limitations: - -* No transport reliability and flexibility (Diameter uses TCP/SCTP instead of UDP). -* No security within protocol (Diameter supports IPSec (mandatory) and TLS (optional)). -* Limited address space for AVPs (Diameter uses 32-bit address space instead of 8-bit). -* Only stateless mode is possible (Diameter supports both stateful and stateless modes). -* Static peers (Diameter offers dynamic discovery, using DNS, SRV and NAPTR). -* No peer alignment capabilities (Diameter introduces capabilities negotiation). -* No support for transport layer failover. - Diameter follows http://tools.ietf.org/html/rfc3539[RFC3539], which introduces correct procedures. -* Limited support for roaming (Diameter introduces mechanisms for secure and scalable roaming). -* No extension possible (Diameter allows extension - new commands and AVPs to be defined). - -Diameter offers all of the capabilities of the RADIUS protocol, and is compatible with RADIUS. -It can also define extensions, or "Applications". - -Each application may introduce new types of messages, AVP codes, and state machines. -The Message and AVP codes are assigned by the . -Each application has its own Application ID and Vendor ID that is used to distinguish between applications. -Application code is used to signal to other peers which operations are supported by the connecting peer (Capabilities Exchange / Negotiation). - -:leveloffset: +1 - -include::Section-Introduction-Message_Format.adoc[] - -:leveloffset: -1 - -[[_introduction_contents]] -== Contents - -&THIS.PLATFORM;Diameter core is built on top of three basic components: - -Stack:: - Extensible Diameter Stack. - It provides basic session support along with application specific sessions. - -Multiplexer (MUX):: - Diameter Stack multiplexer. - Allows different listeners to share the same stack instance. - -Dictionary:: - Diameter Message and AVP Dictionary. - Provides an API to access information about AVPs. - Dictionary is embeded in the MUX. diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc b/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc index 3a4a5827b..ab514fe46 100644 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc +++ b/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc @@ -15,7 +15,7 @@ The Diameter Stack currently supports the following application sessions: * Rf * Cx/Dx * Gx -* Gq' +* Gq * Rx :leveloffset: +1 diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc~ deleted file mode 100644 index e8ee313b9..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc~ +++ /dev/null @@ -1,39 +0,0 @@ -[[_jdiameter]] -= {this-platform} Diameter Stack - -The Diameter Stack is the core component of the presented Diameter solution. -It performs all necessary tasks to allow user interaction with the Diameter network. -It manages the state of diameter peers and allows to route messages between them. -For more details, refer to http://tools.ietf.org/html/rfc3588[RFC 3588]. - -The Diameter Stack currently supports the following application sessions: - -* Base -* Credit Control Application (CCA) -* Sh -* Ro -* Rf -* Cx/Dx -* Gx -* Gq' -* Rx - -:leveloffset: 1 -include::Section-JDiameter-Design_Overview.adoc[] -:leveloffset: 0 - -:leveloffset: 1 -include::Section-JDiameter-Setup.adoc[] -:leveloffset: 0 - -:leveloffset: 1 -include::Section-JDiameter-Configuration.adoc[] -:leveloffset: 0 - -:leveloffset: 1 -include::Section-JDiameter-Source_Overview.adoc[] -:leveloffset: 0 - -:leveloffset: 1 -include::Section-JDiameter-Validator.adoc[] -:leveloffset: 0 diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-MUX.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-MUX.adoc~ deleted file mode 100644 index da8baa6d9..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Chapter-MUX.adoc~ +++ /dev/null @@ -1,44 +0,0 @@ -[[_mux]] -= Multiplexer (MUX) - -The Multiplexer (MUX) is designed as a stack wrapper. -It serves two purposes: - -Expose Stack:: - It exposes the stack and allows it to be shared between multiple listeners. - The stack follows the life cycle of the MUX. - It is created and destroyed with MUX. - -Expose Management Operations:: - Exposes the management operations for clients, one of them being the &MANAGEMENT.PLATFORM; Console. - For specific information please refer to the &THIS.PLATFORM; Diameter Management Console User Guide. - -:leveloffset: +1 - -include::Section-MUX-Design_Overview.adoc[] - -:leveloffset: -1 - -:leveloffset: +1 - -include::Section-MUX-Setup.adoc[] - -:leveloffset: -1 - -:leveloffset: +1 - -include::Section-MUX-Configuration.adoc[] - -:leveloffset: -1 - -:leveloffset: +1 - -include::Section-MUX-Source_Overview.adoc[] - -:leveloffset: -1 - -:leveloffset: +1 - -include::Section-MUX-Dictionary.adoc[] - -:leveloffset: -1 diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Diameter_User_Guide.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Diameter_User_Guide.adoc~ deleted file mode 100644 index 89c9573ab..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Diameter_User_Guide.adoc~ +++ /dev/null @@ -1,43 +0,0 @@ -= User Guide to {this-platform} {this-application} {project-version} -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:sourcedir: . - -:leveloffset: 1 - -include::Book_Info.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::common/Preface.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Chapter-Introduction.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Chapter-JDiameter.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Chapter-MUX.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Revision_History.adoc[] - -:leveloffset: 0 diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-Introduction-Message_Format.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-Introduction-Message_Format.adoc~ deleted file mode 100644 index b5c7f258f..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-Introduction-Message_Format.adoc~ +++ /dev/null @@ -1,86 +0,0 @@ - -[[_mf_message_format]] -= Message Format - -Diameter is a byte based protocol. -Each message has a fixed structure, which consists of two parts: header and payload. - -The message header structure is common for every message. -The content is fixed, as is the length. -Message header content includes the code, application and certain bit flags, which helps identify the message in Diameter scope. - -The message payload is built up of AVPs. -Its content differs for each command and application, though they all define the Session-ID AVP as mandatory. - -.Diameter Message Structure -image::images/dia-Introduction-dia-DiameterPacketFormat.png[] - -The header has the following fields: - -.Message Headers -Version:: - Indicates the Diameter protocol version. - This value is always set to `1`. - -Message Length:: - Indicates the Diameter message length, including the header fields. - -Flags:: - Composed by eight bits, to provide information regarding the message. - The first four bits in the flags octet have the following meaning: - -* R = The message is a request (1) or an answer (0). -* P = The message is proxiable (1) and may be proxied, relayed or redirected, or it must be processed locally (0). -* E = The message is an error message (1) or a regular message (0). -* T = The message is potentially being re-transmitted (1) or being sent for the first time (0). - -The last four bits are reserved for future use, and should be set to 0. - -Command Code:: - Indicates the command associated with the message. - -Application-ID:: - Identifies the application to which the message is applicable for. - The application is an authentication, accounting, or vendor specific application. - The `application-id` in the header must be the same as what is contained in any relevant AVPs in the message. - -Hop-by-Hop ID:: - A unique ID that is used to match requests and answers. - The header field of the answer message must contain the same value present in the corresponding request. - This is how answers are routed back to the peer that sent the message. - -End-to-End ID:: - A time-limited unique ID that is used to to detect duplicate messages. - The ID must be unique for at least four minutes. - The answer message originator must ensure that this header contains the same value present in the corresponding request. - -The message payload is built up from AVPs. -Each AVP has a similar structure: a header, and encoded data. -Data can be simple (eg, integer, long) or complex (another encoded AVP). - -.Payload Structure -image::images/dia-Introduction-dia-DiameterAVPLayout.png[] - -.Payload AVPs -AVP Code:: - Uniquely identifies the attribute, by combining the specified code with the value contained within the Vendor-ID header field. - AVP numbers 1 to 255 are reserved for RADIUS backwards compatibility, and do not require the Vendor-ID header field. AVP numbers 256 and above are used exclusively for the Diameter protocol, and are allocated by IANA. - -Flags:: - Bit flags that specify how each attribute must be handled. - Flags octets have the following structure: V M P r r r r r. - A full description is available in http://tools.ietf.org/html/rfc3588#section-4.1[Section 4.1 of RFC3588]. - The first three bits have the following meaning: - -* V If set, indicates that optional octets (Vendor-ID) is present in AVP header. -* M If set, it indicates that receiveing peer must understand this AVP or send error answer. -* P If set, it indicates the need for encryption for end-to-end security. - -The last 5 bits are reserved for future use, and should be set to 0. - -AVP Length:: - Indicates the number of octets in the AVP, including the following information: - -Vendor-ID:: - An optional octet that identifies the AVP in application space. - AVP code and AVP Vendor-ID create a unique identifier for the AVP. diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc index 753f41468..c55d68de2 100644 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc +++ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc @@ -53,7 +53,7 @@ Further explanation of each child element, and the applicable attributes, is pro The element contains parameters that affect the local Diameter peer. The available elements and attributes are listed for reference. -. Elements and Attributes +=== Elements and Attributes :: Specifies the URI for the local peer. The URI has the following format: "aaa://FQDN:port". @@ -79,28 +79,28 @@ The available elements and attributes are listed for reference. :: Supports child elements that specify the ID of the tracked application(s). It also supports the following properties: -index - Defines the index of this overload monitor, so priorities/orders can be specified. + index::: + Defines the index of this overload monitor, so priorities/orders can be specified. -lowThreshold - The low threshold for activation of the overload monitor. + lowThreshold::: + The low threshold for activation of the overload monitor. -highThreshold - The high threshold for activation of the overload monitor. + highThreshold::: + The high threshold for activation of the overload monitor. :: Parent element containing child elements that specify information about the application. The child elements create a unique application identifier. The child elements are: - -Specifies the vendor ID for application definition. It supports a single property: "value". + ::: + Specifies the vendor ID for application definition. It supports a single property: "value". - -The Authentication Application ID for application definition. It supports a single property: "value". + ::: + The Authentication Application ID for application definition. It supports a single property: "value". - -The Account Application ID for application definition. It supports a single property: "value". + ::: + The Account Application ID for application definition. It supports a single property: "value". :: Contains a child element , which defines the list of default supported applications. @@ -112,8 +112,8 @@ The Account Application ID for application definition. It supports a single prop - - + + @@ -123,6 +123,10 @@ The Account Application ID for application definition. It supports a single prop + + + + @@ -145,7 +149,7 @@ The element contains elements that specify parameters for the Diame The available elements and attributes are listed for reference. If not specified otherwise, each tag supports a single property - "value", which indicates the value of the tag. -. Elements and Attributes +=== Elements and Attributes :: Specifies whether the stack will accept connections from undefined peers. The default value is `false`. @@ -197,6 +201,26 @@ If not specified otherwise, each tag supports a single property - "value", which Determines how long it takes for the reconnection procedure to timeout. The delay is in milliseconds. +:: + Sets the value of Tx timer as specified in http://tools.ietf.org/html/rfc4006#section-13[Section 13 of RFC4006]. + Namely, it controls the waiting time in the client in the Pending state (upon request dispatch). + The delay is in milliseconds. + +:: + Controls the total response timeout that is strictly related to [parameter]`TxTimeOut` timer and determines the total waiting time + in the Pending state including all possible Tx timer expiries along with corresponding retransmissions if any happened. + Namely, defines how long the stack should wait for the answer message from remote peers and carry on with retransmissions in case of + delivery failures before providing request failure notification to the application. + The delay is in milliseconds. + +:: + Defines a comma delimited list of protocol errors received in Result-Code AVP (as defined in https://tools.ietf.org/html/rfc6733#section-7.1[Section 7.1 of RFC6733]) + which make an initial request to be retransmitted to another remote peer (with T flag set to `false`). + +:: + Determines how much time the persistence record should be kept if there is no request sent within a session. + Irrelevant when session persistent routing is not enabled. The delay is in seconds. + :: Determines the number of threads for handling events in the Peer FSM. @@ -205,37 +229,37 @@ If not specified otherwise, each tag supports a single property - "value", which It supports multiple [parameter]`Entity` child elements. [parameter]`Entity` elements configure thread groups. These elements support the following properties: -name -Specifies the name of the entity. - -size -Specifies the thread pool size of the entity. + name::: + Specifies the name of the entity. + size::: + Specifies the thread pool size of the entity. ++ The default supported entities are: -ThreadGroup -Determines the maximum thread count in other entities. + ThreadGroup::: + Determines the maximum thread count in other entities. -ProcessingMessageTimer -Determines the thread count for message processing tasks. + ProcessingMessageTimer::: + Determines the thread count for message processing tasks. -DuplicationMessageTimer -Specifies the thread pool for identifying duplicate messages. + DuplicationMessageTimer::: + Specifies the thread pool for identifying duplicate messages. -RedirectMessageTimer -Specifies the thread pool for redirecting messages that do not need any further processing. + RedirectMessageTimer::: + Specifies the thread pool for redirecting messages that do not need any further processing. -PeerOverloadTimer -Determines the thread pool for managing the overload monitor. + PeerOverloadTimer::: + Determines the thread pool for managing the overload monitor. -ConnectionTimer -Determines the thread pool for managing tasks regarding peer connection FSM. + ConnectionTimer::: + Determines the thread pool for managing tasks regarding peer connection FSM. -StatisticTimer -Determines the thread pool for statistic gathering tasks. + StatisticTimer::: + Determines the thread pool for statistic gathering tasks. -ApplicationSession -Determines the thread pool for managing the invocation of application session FSMs, which will invoke listeners. + ApplicationSession::: + Determines the thread pool for managing the invocation of application session FSMs, which will invoke listeners. [source,xml] ---- @@ -262,40 +286,40 @@ Determines the thread pool for managing the invocation of application session FS The element contains elements that specify parameters for external peers. The available elements and attributes are listed for reference. -. Elements and Attributes +=== Elements and Attributes :: Parent element containing the child element , which specifies external peers and the way they connect. specifies the name of external peers, whether they should be treated as a server or client, and what rating the peer has externally. - ++ supports the following properties: -name -Specifies the name of the peer in the form of a URI. The structure is "aaa://[fqdn|ip]:port" (for example, "aaa://192.168.1.1:3868"). + name::: + Specifies the name of the peer in the form of a URI. The structure is "aaa://[fqdn|ip]:port" (for example, "aaa://192.168.1.1:3868"). -attempt_connect -Determines if the stack should try to connect to this peer. This property accepts boolean values. + attempt_connect::: + Determines if the stack should try to connect to this peer. This property accepts boolean values. -rating -Specifies the rating of this peer in order to achieve peer priorities/sorting. + rating::: + Specifies the rating of this peer in order to achieve peer priorities/sorting. :: Parent element containing the child element , which specifies all realms that connect into the Diameter network. contains attributes and elements that describe different realms configured for the Core. It supports child elements, which define the applications supported. - ++ supports the following parameters: -peers -Comma separated list of peers. Each peer is represented by an IP Address or FQDN. + peers::: + Comma separated list of peers. Each peer is represented by an IP Address or FQDN. -local_action -Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. + local_action::: + Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. -dynamic -Specifies if this realm is dynamic. That is, peers that connect to peers with this realm name will be added to the realm peer list if not present already. + dynamic::: + Specifies if this realm is dynamic. That is, peers that connect to peers with this realm name will be added to the realm peer list if not present already. -exp_time -The time before a peer belonging to this realm is removed if no connection is available. + exp_time::: + The time before a peer belonging to this realm is removed if no connection is available. Below is an example configuration file for a server supporting the CCA, Sh and Ro Applications: @@ -336,6 +360,10 @@ Below is an example configuration file for a server supporting the CCA, Sh and R + + + + @@ -495,3 +523,81 @@ The following content is sufficient for the JBoss Cache configuration file: ---- + +[[_jdiameter_failover_configuration]] +== Failover configuration + +Apart from a default routing scheme, which does not require any additional configuration, +there is an option of activating failure aware routing that extends capabilities of basic +router with extra features related to failure detection, peer priority handling and load +balancing. Rating of a particular peer is taken into consideration when deciding about +an order of peers usage in case of failure detection. The highest rating peers are used first, +then lower priorities peers next, etc. If several peers are marked with the same rating, +load balancing algorithm is executed among them. In case of all higher priority peers failure, +lower priority peers are considered. Afterwards, in case any higher priority peer becomes +available again and session persistence is enabled as well, only new sessions requests are +targeted again to higher priority peers, i.e. currently handled session stays assigned to +the peer selected beforehand. + +In order to enable a/m extended routing feature, the following entry has to be added to the `Extensions` +section of [path]_jdiameter-config.xml_: + +[source,xml] +---- +org.jdiameter.server.impl.FailureAwareRouter +---- + +The above mentioned feature of failure aware routing is based on a failure detection mechanism which can report either peer unavailability or +request delivery failure. As such, it can take place in the event of any of the following situations: + +* peer is marked as unavailable by Diameter Base watchdog mechanism defined in http://tools.ietf.org/html/rfc3539#section-3.4[Section 3.4 of RFC3539] +and http://tools.ietf.org/html/rfc3588#section-5.6[Section 5.6 of RFC3588] +* an error code, which is included in [parameter]`RetransmissionRequiredResCodes` list, is received in Result-Code AVP from the remote peer +* either Tx timeout (specified by [parameter]`TxTimeOut` configuration parameter) or retransmission timeout (specified by [parameter]`RetransmissionTimeOut` +configuration parameter) have expired + +When there is an ongoing session and regardless of failure aware routing being enabled or not, failure detection mechanism can perform one or multiple +retransmissions of a request which delivery failure had been reported for. The decision, whether to retransmit or not, is determined by the value of +Credit-Control-Failure-Handling AVP received from the remote peer beforehand. If CCFH action had not been imposed by the remote peer, a default `CONTINUE` +action is assumed. When it comes to specific failure procedures, following recommendations stated in http://tools.ietf.org/html/rfc4006#section-5.7[Section 5.7 of RFC4006], +the Diameter stack implements several modes of behaviour: + +,=== +CCFH value,Event,Action + +CONTINUE / RETRY_AND_TERMINATE,Tx timeout expired,attempt retransmission (T flag set to `true`) +TERMINATE,Tx timeout expired,report `RequestTxTimeout` event +CONTINUE / RETRY_AND_TERMINATE,error result code returned (included in [parameter]`RetransmissionRequiredResCodes`),attempt retransmission (T flag set to `false`) +TERMINATE,error result code returned (included in [parameter]`RetransmissionRequiredResCodes`),attempt retransmission (T flag set to `false`) +CONTINUE / RETRY_AND_TERMINATE,retransmission timeout expired,report `RequestTxTimeout` event +,=== + +Additionally, along with an extended routing policy, it is also highly advised to enable session +persistence as well. Otherwise, routing decisions will be made for every single request within +a particular session what may eventually result in multiple undesirable reselections of remote +destination peer. + +[[_jdiameter_session_persistence_configuration]] +== Session persistence + +Session persistence enforces sticky sessions that map a single diameter session to a single peer +which had been selected to process such a session. Session persistence record is created after +a peer had answered the first (initial) request for that session. Furthermore, it can be updated +in the event of peer reselection by failover algorithm. Finally, it is removed when session is finished +normally, an error indication answer is received or session inactivity timeout expires. Replication of +session persistence records is not supported. + +The following list defines the requirements for enabling session persistence: + +* Add the following entry to the `Parameters` section of [path]_jdiameter-config.xml_: ++ +[source,xml] +---- +org.jdiameter.common.impl.data.RoutingAwareDataSource +---- + +* Customize the value of `SessionInactivityTimeOut` in the `Extensions` section of [path]_jdiameter-config.xml_ + +If enabled, session persistence feature supports two types of applications, i.e. CCA (defined in +http://tools.ietf.org/html/rfc4006[RFC4006]) and Ro (defined in http://www.3gpp.org/DynaReport/32240.htm[3GPP TS 32.240] +and http://www.3gpp.org/DynaReport/32299.htm[3GPP TS 32.299]) by virtue of their session based specificity. diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc~ deleted file mode 100644 index 439ea71ae..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc~ +++ /dev/null @@ -1,498 +0,0 @@ - -[[_jdiameter_configuration]] -= Diameter Stack Configuration - -The stack is initially configured by parsing an XML file. -The top level structure of the file is described below. -Further explanation of each child element, and the applicable attributes, is provided later in this section. - -[source,xml] ----- - - - - - - - - ----- - -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- - -The element contains parameters that affect the local Diameter peer. -The available elements and attributes are listed for reference. - -. Elements and Attributes -:: - Specifies the URI for the local peer. - The URI has the following format: "aaa://FQDN:port". - -:: - Contains one or more child element, which contain a single, valid IP address for the local peer, stored in the [parameter]`value` attribute of the IPAddress. - -:: - Specifies the realm of the local peer, using the [parameter]`value` attribute. - -:: - Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA. - -:: - Specifies the name of the local peer product. - -:: - Specifies the version of the firmware. - -:: - Optional parent element containing child elements that specify settings relating to the Overload Monitor. - -:: - Supports child elements that specify the ID of the tracked application(s). It also supports the following properties: - -index - Defines the index of this overload monitor, so priorities/orders can be specified. - -lowThreshold - The low threshold for activation of the overload monitor. - -highThreshold - The high threshold for activation of the overload monitor. - -:: - Parent element containing child elements that specify information about the application. - The child elements create a unique application identifier. - The child elements are: - - -Specifies the vendor ID for application definition. It supports a single property: "value". - - -The Authentication Application ID for application definition. It supports a single property: "value". - - -The Account Application ID for application definition. It supports a single property: "value". - -:: - Contains a child element , which defines the list of default supported applications. - It is used for the server side, when the stack is configured to accept incoming calls and there is an empty list of preconfigured peers (server is configured to accept any connection). - -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- - -The element contains elements that specify parameters for the Diameter stack. -The available elements and attributes are listed for reference. -If not specified otherwise, each tag supports a single property - "value", which indicates the value of the tag. - -. Elements and Attributes -:: - Specifies whether the stack will accept connections from undefined peers. - The default value is `false`. - -:: - Specifies whether duplicate message protection is enabled. - The default value is `false`. - -:: - Specifies the time each duplicate message is valid for (in extreme cases, it can live up to 2 * DuplicateTimer - 1 milliseconds). The default, minimum value is `240000` (4 minutes in milliseconds). - -:: - Specifies the number of requests stored for duplicate protection. - The default value is `5000`. - -:: - Determines whether the URI should be used as FQDN. - If it is set to `true`, the stack expects the destination/origin host to be in the format of "aaa://isdn.domain.com:3868" rather than the normal "isdn.domain.com". The default value is `false`. - -:: - Determines how many tasks the peer state machine can have before rejecting the next task. - This queue contains FSM events and messaging. - -:: - Determines the timeout for messages other than protocol FSM messages. - The delay is in milliseconds. - -:: - Determines how long the stack waits for all resources to stop. - The delays are in milliseconds. - -:: - Determines how long it takes for CER/CEA exchanges to timeout if there is no response. - The delays are in milliseconds. - -:: - Determines how long the stack waits to retry the communication with a peer that has stopped answering DWR messages. - The delay is in milliseconds. - -:: - Determines how long it takes for a DWR/DWA exchange to timeout if there is no response. - The delay is in milliseconds. - -:: - Determines how long it takes for a DPR/DPA exchange to timeout if there is no response. - The delay is in milliseconds. - -:: - Determines how long it takes for the reconnection procedure to timeout. - The delay is in milliseconds. - -:: - Determines the number of threads for handling events in the Peer FSM. - -:: - Controls the thread pool sizes for different aspects of the stack. - It supports multiple [parameter]`Entity` child elements. [parameter]`Entity` elements configure thread groups. - These elements support the following properties: - -name -Specifies the name of the entity. - -size -Specifies the thread pool size of the entity. - -The default supported entities are: - -ThreadGroup -Determines the maximum thread count in other entities. - -ProcessingMessageTimer -Determines the thread count for message processing tasks. - -DuplicationMessageTimer -Specifies the thread pool for identifying duplicate messages. - -RedirectMessageTimer -Specifies the thread pool for redirecting messages that do not need any further processing. - -PeerOverloadTimer -Determines the thread pool for managing the overload monitor. - -ConnectionTimer -Determines the thread pool for managing tasks regarding peer connection FSM. - -StatisticTimer -Determines the thread pool for statistic gathering tasks. - -ApplicationSession -Determines the thread pool for managing the invocation of application session FSMs, which will invoke listeners. - -[source,xml] ----- - - - - - - - - - - - - - - - - - - ----- - -The element contains elements that specify parameters for external peers. -The available elements and attributes are listed for reference. - -. Elements and Attributes -:: - Parent element containing the child element , which specifies external peers and the way they connect. - specifies the name of external peers, whether they should be treated as a server or client, and what rating the peer has externally. - - supports the following properties: - -name -Specifies the name of the peer in the form of a URI. The structure is "aaa://[fqdn|ip]:port" (for example, "aaa://192.168.1.1:3868"). - -attempt_connect -Determines if the stack should try to connect to this peer. This property accepts boolean values. - -rating -Specifies the rating of this peer in order to achieve peer priorities/sorting. - -:: - Parent element containing the child element , which specifies all realms that connect into the Diameter network. - contains attributes and elements that describe different realms configured for the Core. - It supports child elements, which define the applications supported. - - supports the following parameters: - -peers -Comma separated list of peers. Each peer is represented by an IP Address or FQDN. - -local_action -Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. - -dynamic -Specifies if this realm is dynamic. That is, peers that connect to peers with this realm name will be added to the realm peer list if not present already. - -exp_time -The time before a peer belonging to this realm is removed if no connection is available. - - - -Below is an example configuration file for a server supporting the CCA, Sh and Ro Applications: - -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- - -[[_jdiameter_cluster_configuration]] -== Cluster configuration - -The following list defines the requirements for enabling stack cluster mode - -* Add the following entries to the `Parameters` section of [path]_jdiameter-config.xml_: -+ -[source,xml] ----- - - -org.mobicents.diameter.impl. ha.data.ReplicatedData -org.mobicents.diameter.impl.ha. timer.ReplicatedTimerFacilityImpl ----- - -* A proper `JBoss Cache` configuration file: [path]_jdiameter-jbc.xml_ (located in the [path]_config_ directory). -+ -The following content is sufficient for the JBoss Cache configuration file: -+ -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Setup.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Setup.adoc~ deleted file mode 100644 index 599d0b3c8..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Setup.adoc~ +++ /dev/null @@ -1,69 +0,0 @@ - -[[_jdiameter_setup]] -= {this-platform} Diameter Stack Setup - -[[_jdiameter_preinstall_requirements_and_prerequisites]] -== Pre-Install Requirements and Prerequisites - -Ensure that the following requirements have been met before continuing with the install. - -[[_jdiameter_hardware_requirements]] -=== Hardware Requirements - -{this-platform} Diameter Stack does not have any hardware requirements. - -[[_jdiameter_software_prerequisites]] -=== Software Prerequisites - -{this-platform} Diameter Stack has the following software dependencies: - -* Pico Container -* slf4j - -Clustered setup also requires following: - -* JDiameter HA -* JBoss Cache - -[[_jdiameter_source_code]] -== Source Code - -This section provides instructions on how to obtain and build the {this-platform} Diameter Stack from source code. - -[[_jdiameter_release_source_building]] -=== Release Source Code Building - - -. Downloading the source code -+ -IMPORTANT: Subversion is used to manage its source code. -Instructions for using Subversion, including install, can be found at http://svnbook.red-bean.com -+ -Use SVN to checkout a specific release source, the base URL is {this-trunk-source-code-url} , then add the specific release version, lets consider &THIS.VERSION;. -+ -[source] ----- -[usr]$ git clone git@github.com:RestComm/jss7.git ----- - -. Building the source code -+ -IMPORTANT: Maven 3.2.5 (or higher) is used to build the release. -Instructions for using Maven2, including install, can be found at http://maven.apache.org -+ -Use Maven to build the deployable unit binary. -+ -[source] ----- - - [usr]$ cd - - [usr]$ mvn install ----- -+ -Once the process finishes you should have the files deployed in maven archive. - - -[[_jdiameter_trunk_source_building]] -=== Development Trunk Source Building - -Follow the process in <<_jdiameter_release_source_building>>, replacing the SVN source code URL with &THIS.JDIAMETER_TRUNK_SOURCE_CODE_URL;. diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Source_Overview.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Source_Overview.adoc~ deleted file mode 100644 index c82ecadd6..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Source_Overview.adoc~ +++ /dev/null @@ -1,313 +0,0 @@ - -[[_jdiameter_source_overview]] -= Diameter Stack Source overview - -Diameter stack is built with the following basic components: - - - -Session Factory:: - The Session Factory governs the creation of sessions - raw and specific application sessions. - -Raw and Application Sessions:: - Sessions govern stateful message routing between peers. - Specific application sessions consume different type of messages and act differently based on the data present. - -Stack:: - The Stack governs all necessary components, which are used to establish connection and communicate with remote peers. - -NOTE: For more detailed information, please refer to the Javadoc or the simple examples that can be found here: https://github.com/RestComm/jdiameter/tree/master/testsuite/load[Git Testsuite HEAD]. - -[[_jdiameter_source_overview_session_factory]] -== Session Factory - -[class]`SessionFactory` provides the stack user with access to session objects. -It manages registered application session factories in order to allow for the creation of specific application sessions. -A Session Factory instance can be obtained from the stack using the [method]`getSessionFactory()` method. -The base [class]`SessionFactory` interface is defined below: - -[source,java] ----- -package org.jdiameter.api; - -import org.jdiameter.api.app.AppSession; - -public interface SessionFactory { - - RawSession getNewRawSession() throws InternalException; - - Session getNewSession() throws InternalException; - - Session getNewSession(String sessionId) throws InternalException; - - T getNewAppSession(ApplicationId applicationId, - Class userSession) throws InternalException; - - T getNewAppSession(String sessionId, ApplicationId - applicationId, Class userSession) throws InternalException; -} ----- - -However, since the stack is extensible, it is safe to cast the [class]`SessionFactory` object to this interface: - -[source,java] ----- -package org.jdiameter.client.api; - - -public interface ISessionFactory extends SessionFactory { - - T getNewAppSession(String sessionId, - ApplicationId applicationId, java.lang.Class - aClass, Object... args) throws InternalException; - - void registerAppFacory(Class sessionClass, - IAppSessionFactory factory); - - void unRegisterAppFacory(Class sessionClass); - - IConcurrentFactory getConcurrentFactory(); - -} ----- - -[method]`RawSession getNewRawSession() throws InternalException;`:: - This method creates a [class]`RawSession`. - Raw sessions are meant as handles for code performing part of the routing decision on the stack's, such as rely agents for instance. - -[method]`Session getNewSession() throws InternalException;`:: - This method creates a session that acts as the endpoint for peer communication (for a given session ID). It declares the method that works with the [class]`Request` and [class]`Answer` objects. - A session created with this method has an autogenerated ID. - It should be considered as a client session. - -[method]`Session getNewSession(String sessionId) throws InternalException;`:: - As above. - However, the created session has an ID equal to that passsed as an argument. - This created session should be considered a server session. - -[method]` T getNewAppSession(ApplicationId applicationId, Class userSession) throws InternalException;`:: - This method creates a new specific application session, identified by the application ID and class of the session passed. - The session ID is generated by implementation. - New application sessions should be considered as client sessions. - It is safe to type cast the return value to class passed as an argument. - This method delegates the call to a specific application session factory. - -[method]` T getNewAppSession(String sessionId, ApplicationId applicationId, Class userSession) throws InternalException;`:: - As above. - However, the session Id is equal to the argument passed. - New sessions should be considered server sessions. - -[method]` T getNewAppSession(String sessionId, ApplicationId applicationId, java.lang.Class aClass, Object... args) throws InternalException;`:: - As above. - However, it allows the stack to pass some additional arguments. - Passed values are implementation specifc. - -[method]`void registerAppFacory(Class sessionClass, IAppSessionFactory factory);`:: - Registers the [parameter]`factory` for a certain [parameter]`sessionClass`. - This factory will receive a delegated call when ever the [method]`getNewAppSession` method is called with an application class matching one from the register method. - -[method]`void unRegisterAppFacory(Class sessionClass);`:: - Removes the application session factory registered for the [parameter]`sessionClass`. - -.SessionFactory use example -==== -[source,java] ----- -class Test implements EventListener -{ - -.... -public void test(){ - Stack stack = new StackImpl(); - XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile)); - - SessionFactory sessionFactory = stack.init(config); - stack.start(); - //perferctly legal, both factories are the same. - sessionFactor = stack.getSessionFactory(); - Session session = sessionFactory.getNewSession(); - session.setRequestListener(this); - Request r = session.createRequest(308,ApplicationId.createByAuth(100L,10101L), - "mobicents.org","aaa://uas.fancyapp.mobicents.org"); - - //add avps specific for app - session.send(r,this); - } -} ----- -==== - -.SessionFactory use example -==== -[source,java] ----- -class Test implements EventListener -{ - Stack stack = new StackImpl(); - XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile)); - - ISessionFactory sessionFactory = (ISessionFactory)stack.init(config); - stack.start(); - //perferctly legal, both factories are the same. - sessionFactor = (ISessionFactory)stack.getSessionFactory(); - sessionFactory.registerAppFacory(ClientShSession.class, new ShClientSessionFactory(this)); - - //our implementation of factory does not require any parameters - ClientShSession session = (ClientShSession) sessionFactory.getNewAppSession(null, null - , ClientShSession.class, null); - - ... - session.sendUserDataRequest(udr); -} ----- -==== - -[[_jdiameter_source_overview_session]] -== Sessions - -[class]`RawSessions`, [class]`Sessions` and [class]`ApplicationSessions` provide the means for dispatching and receiving messages. -Specific implementation of [class]`ApplicationSession` may provide non standard methods. - -The [class]`RawSession` and the [class]`Session` life span is controlled entirely by the application. -However, the [class]`ApplicationSession` life time depends on the implemented state machine. - -[class]`RawSession` is defined as follows: - -[source,java] ----- -public interface BaseSession extends Wrapper, Serializable { - - long getCreationTime(); - - long getLastAccessedTime(); - - boolean isValid(); - - Future send(Message message) throws InternalException, - IllegalDiameterStateException, RouteException, OverloadException; - - Future send(Message message, long timeOut, TimeUnit timeUnit) - throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; - - void release(); -} - -public interface RawSession extends BaseSession { - - Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp); - - Message createMessage(int commandCode, ApplicationId applicationId, - long hopByHopIdentifier, long endToEndIdentifier, Avp... avp); - - Message createMessage(Message message, boolean copyAvps); - - void send(Message message, EventListener listener) - throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; - - void send(Message message, EventListener listener, - long timeOut, TimeUnit timeUnit) throws InternalException, - IllegalDiameterStateException, RouteException, OverloadException; -} ----- - -[method]`long getCreationTime();`:: - Returns the time stamp of this session creation. - -[method]`long getLastAccessedTime();`:: - Returns the time stamp indicating the last sent or received operation. - -[method]`boolean isValid();`:: - Returns `true` when this session is still valid (ie, [method]`release()` has not been called). - -[method]`void release();`:: - Application calls this method to inform the user that the session should free any associated resource - it shall not be used anymore. - -[method]`Future send(Message message)`:: - Sends a message in async mode. - The [class]`Future` reference provides the means of accessing the answer once it is received - -[method]`void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit)`:: - As above. - Allows to specify the time out value for send operations. - -[method]`Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp);`:: - Creates a Diameter message. - It should be explicitly set either as a request or answer. - Passed parameters are used to build messages. - -[method]`Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp);`:: - As above. - However, it also allows for the Hop-by-Hop and End-to-End Identifiers in the message header to be set. - This method should be used to create answers. - -[method]`Message createMessage(Message message, boolean copyAvps);`:: - Clones a message and returns the created object. - The copyAvps parameter defines whether basic AVPs (Session, Route and Proxy information) should be copied to the new object. - -[method]`void send(Message message, EventListener listener)`:: - Sends a message. - The answer will be delivered by the specified listener - -[method]`void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit)`:: - As above. - It also allows for the answer to be passed after timeout. - -[class]`Session` defines similar methods, with exactly the same purpose: - -[source,java] ----- -public interface Session extends BaseSession { - String getSessionId(); - - void setRequestListener(NetworkReqListener listener); - - Request createRequest(int commandCode, ApplicationId appId, String destRealm); - - Request createRequest(int commandCode, ApplicationId appId, String destRealm, String destHost); - - Request createRequest(Request prevRequest); - - void send(Message message, EventListener listener) - throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; - - void send(Message message, EventListener listener, long timeOut, - TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, - RouteException, OverloadException; -} ----- - -== Application Session Factories - -In the table below, you can find session factories provided by current implementation, along with a short description: - -.Application Factories -[cols="1,1,1,1", frame="all", options="header"] -|=== -| Factory class -| Application type & id -| Application -| Reference -| RFC3588 - -| RFC3588 - -| RFC4006 - -| TS.29328, TS.29329 - -| TS.29228, TS.29229 - -| TS.29228, TS.29229 - -| TS.32240 - -| TS.32240 -|=== - -NOTE: There is no specific factory for Ro and Rf. -Those applications reuse the respective session and session factories. - -NOTE: Application IDs contain two numbers - [VendorId:ApplicationId]. - -IMPORTANT: Spaces have been introduced in the `Factory class` column values to correctly render the table. -Please remove them when using copy/paste. diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Configuration.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Configuration.adoc~ deleted file mode 100644 index e055ddc56..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Configuration.adoc~ +++ /dev/null @@ -1,263 +0,0 @@ - -[[_jdiameter_validator_configuration]] -= Validator Configuration - -The Validator is configured with a single XML file. -This file contains the structure definition for both messages and AVPs. - -Upon creation of the Diameter Stack, the validator is initialized. -It performs the initialization by looking up the [path]_dictionary.xml_ file in classpath. - -NOTE: The configuration file contains more data that `Validator` uses to build its data base. -This is because the `Dictionary` uses the same file to configure itself. -It reuses the AVP definitions, with some extra information like AVP type and flags. - -The configuration file has the following structure: - -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - ----- - -:: - The root element that contains the child elements comprising the validator and dictionary components. - This element does not support any attributes. - -:: - Specifies whether message validation is activated for sent and received stack messages. - The element supports the following optional attributes: - -enabled -Specifies whether the validator is activated or deactivated. If not specified, the validator is deactivated. - -sendLevel -Determines the validation level for messages sent by the stack instance. Values determine if sent messages are not validated at all (OFF), only message level AVPs are checked (MESSAGE) or all AVPs are checked (ALL). - -receiveLevel -Determines the validation level for messages received by the stack instance. Values determine if sent messages are not validated at all (OFF), only message level AVPs are checked (MESSAGE) or all AVPs are checked (ALL). - -:: - Optional element that specifies the mapping between the vendor name, vendor ID, and vendor code. - The element supports the following required attributes: - -name -Specifies the vendor name. For example, "Hewlett Packard". - -vendor-id -Specifies the unique ID associated with the vendor. For example, "HP". - -code -Specifies the alpha-numeric code allocated to the vendor by IANA. For example, "11". The value must be unique for each declaration. - -. XML Attributes -==== -[source,xml] ----- -... - - - - - - - - - - - - ----- -==== - -:: - Defines the simple Attribute Value Pair (AVP) types. - The element supports the following required attributes: - -type-name -Specifies a type name in accordance with the acceptable base types defined in RFC 3588. For example; "Enumerated", "OctetString", "Integer32". - -type-parent -Specifies the parent type name used to define the base characteristics of the type. The values are restricted to defined elements. For example; "OctetString", "UTF8String", "IPAddress". - -. XML Attributes -==== -[source,xml] ----- - - - - - - - - - - - - - - ----- -==== - -:: - Defines the specific applications used within the dictionary. - Two child elements are supported by : and . - -The element supports the following attributes: - -id -Specifies the unique ID allocated to the application. The attribute is used in all messages and forms part of the message header. - -name -Optional attribute that specifies the logical name of the application. - -uri -Optional attribute that specifies a link to additional application information. - - -. XML Attributes -==== -[source,xml] ----- - ----- -==== - -:: - Element containing information necessary to configure the Attribute Value Pairs. <<_table_avp_attributes>> contains the complete list of supported attributes, and their available values (if applicable). - The element supports a number of child elements that are used to set finer parameters for the individual AVP. The supported elements are , , and . - -NOTE: Different sets of elements are supported by depending on its position in the dictionary.xml file. - -. Child Elements and Attributes -==== -[source,xml] ----- - - - - - - - - - - - - - ----- -==== - -:: - Child element of that is used to match the AVP with the AVP type as defined in the element. - The element supports the following mandatory attribute: - -type-name -Specifies the type-name of the element. This is used to match the type-name value in the element. - -NOTE: is ignored if the element contains the element. - -:: - Child element of that specifies the enumeration value for the specified AVP. - is used only when the type-name attribute of is specified. - The element supports the following mandatory attributes: - -name -Specifies the name of a constant value that applies to the AVP. - -code -Specifies the integer value associated with the name of the constant. The value is passed as a value of the AVP, and maps to the name attribute. - -NOTE: is ignored if the element contains the element. - -:: - Child element of that specifies the AVP is a grouped type. - A grouped AVP is one that has no element present. - The element does not support any attributes, however the element is allowed as a child element. - -The , which specifies a reference to a grouped AVP, supports one mandatory attribute: - -name -Specifies the name of the grouped AVP member. The value must match the defined AVP name. - - -. Attributes -[cols="1,1,1", frame="all", options="header"] -|=== -| Attribute Name (optional in brackets) | Explicit Values (default in brackets) | Description -| name | | Specifies the name of the AVP. This is used to match the AVP definition to any grouped AVP references. For further information about grouped AVPs, refer to the element description in this section. -| code | | Specifies the integer code of the AVP. -| (vendor-id) | (none) | Used to match the vendor ID reference to the value defined in the element. -| (multiplicity) | | Specifies the number of acceptable AVPs in a message using an explicit value. -| | 0 | An AVP must not be present in the message. -| | (0+) | Zero or more instances of the AVP must be present in the message. -| | 0-1 | Zero, or one instance of the AVP may be present in the message. An error occurs if the message contains more than one instance of the AVP. -| | 1 | One instance of the AVP must be present in the message. -| | 1+ | At least one instance of the AVP must be present in the message. -| may-encrypt | Yes \| (No) | Specifies whether the AVP can be encrypted. -| protected | may \| must \| mustnot | Determines actual state of AVP that is expected, if it MUST be encrypted , may or MUST NOT. -| vendor-bit | must \| mustnot | Specifies whether the Vendor ID should be set. -| mandatory | may \| must \| mustnot | Determines if support for this AVP is mandatory in order to consume/process message. -| vendor | | Specifies the defined vendor code, which is used by the child element -|=== - -. XML Attributes -==== -[source,xml] ----- - - - - - - - - - - - ----- -==== - -:: - Specifies the command for the application. - The element supports the element, which specifies the structure of the command. - The element supports the following attributes: - -NOTE: If the element is specified in , it does not support any child elements. -The element only refers to defined AVPs when used in this context. - -. Elements and Attributes -==== -[source,xml] ----- - - - ----- -==== diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Source_Overview.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Source_Overview.adoc~ deleted file mode 100644 index 92c3bdf71..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Source_Overview.adoc~ +++ /dev/null @@ -1,63 +0,0 @@ - -[[_jdiameter_validator_source_overview]] -= Validator Source Overview - -The Validator API defines methods to access its database of AVPs and check if the AVP and message have the proper structure. - -The Validator is currently message oriented. -This means that it declares methods that center on message consistency checks. -The class containing all validation logic is [class]`org.jdiameter.common.impl.validation.DiameterMessageValidator`. -It exposes the following methods: - -public boolean isOn();:: - Simple method to determine if the `Validator` is enabled. - -public ValidatorLevel getSendLevel(); - :: - Returns the validation level of outgoing messages. - It can have one of the following values: `OFF`, `MESSAGE`, `ALL`. - -public ValidatorLevel getReceiveLevel():: - Returns the validation level of incoming messages. - It can have one of the following values: `OFF`, `MESSAGE`, `ALL`. - -public void validate(Message msg, boolean incoming) throws JAvpNotAllowedException:: - Performs validation on a message. - Based on the [parameter]`incoming` flag, the correct validation level is applied. - If validation fails, an exception with details is thrown. - -public void validate(Message msg, ValidatorLevel validatorLevel) throws JAvpNotAllowedException:: - Performs validation on messages with a specified level. - It is a programatical way to allow different levels of validation from those configured. - If validation fails, a [class]`JAvpNotAllowedException` with details is thrown. - -NOTE: The current implementation provides more methods, however those are out of scope for this documentation. - -A simple example of a Validator use case is shown below: - -.Validator Message Check Example -==== -The example below is pseudo-code. - -[source,java] ----- - -... -boolean isRequest = true; -boolean isIncoming = false; - -DiameterMessageValidator messageValidator = DiameterMessageValidator.getInstance(); -Message message = createMessage(UserDataRequest.MESSAGE_CODE, isRequest, - applicationId); - -//add AVPs -... -//perform check -try{ - messageValidator.validate(message, isIncoming); -} -catch(JAvpNotAllowedException e) { - System.err.println("Failed to validate ..., avp code: " + e.getAvpCode() + " avp vendor:" + e.getVendorId() + ", message:" + e.getMessage()); -} ----- -==== \ No newline at end of file diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator.adoc~ deleted file mode 100644 index 508098d79..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator.adoc~ +++ /dev/null @@ -1,36 +0,0 @@ - -[[_jdiameter_validator]] -= Diameter Stack Validator - -Validator is one of the Stack features. -The primary purpose of the Validator is to detect malformed messages, such as an Answer message containing a Destination-Host Attribute Value Pair (AVP). - -The Validator is capable of validating multi-leveled, grouped AVPs, excluding the following content types: - -* URI, or Identifier types. -* Enumerated types against defined values. - -The Validator is only capable of checking structural integrity, not the content of the message. - -The Validator performs the following checks: - -Index:: - Checks that the AVPs are in the correct place. - For example, `Session-Id` must always be encoded before any other AVP. - -Multiplicity:: - Checks that the message AVPs occur the proper number of times. - For example, the Session-ID should only be present once. - -The `Validator` is called by the stack implementation. -It is invoked after the message is received, but before it is dispatched to a remote peer. - -NOTE: This means that if the peer does not exist in the local peer table, the validator is not called, as the stack fails before calling it. - -:leveloffset: 1 -include::Section-JDiameter-Validator-Configuration.adoc[] -:leveloffset: 0 - -:leveloffset: 1 -include::Section-JDiameter-Validator-Source_Overview.adoc[] -:leveloffset: 0 \ No newline at end of file diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc b/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc index fca0f073d..589a6216e 100644 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc +++ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc @@ -55,11 +55,25 @@ Use Maven to build the deployable unit binary. [usr]$ mvn install ---- + +If one expects the final build to include configuration file with both of extra features enabled, i.e. +failover and session persistence mentioned in <<_jdiameter_failover_configuration>> and +<<_jdiameter_session_persistence_configuration>> chapters accordingly, the same [app]`maven` command +ought to be run but with the profile switch included: `-Pfailover-config-enabled`. Below are three examples +for different versions of JBoss each: ++ +[source] +---- + +[usr]$ mvn -Pjboss4,failover-config-enabled install +[usr]$ mvn -Pjboss5,failover-config-enabled install +[usr]$ mvn -Pjboss7,failover-config-enabled install +---- ++ Once the process finishes you should have the SAR built. If the [var]`JBOSS_HOME` environment variable is set, the will be deployed in the container after execution. -NOTE: By default {this-platform} Diameter MUX; deploys in the {jee-platform} v5.x . +NOTE: By default {this-platform} Diameter MUX deploys in the {jee-platform} v5.x . To change it, run [app]`maven` with the profile switch command: [parameter]`-Pjboss4`. [[_mux_trunk_source_building]] diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc~ deleted file mode 100644 index 71f28c684..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc~ +++ /dev/null @@ -1,68 +0,0 @@ - -[[_mux_setup]] -= Diameter Multiplexer (MUX) Setup - -[[_mux_preinstall_requirements_and_prerequisites]] -== Pre-Install Requirements and Prerequisites - -Ensure that the following requirements have been met before continuing with the installation process. - -[[_mux_hardware_requirements]] -=== Hardware Requirements - -MUX does not have any hardware requirements. - -[[_mux_software_prerequisites]] -=== Software Prerequisites - -MUX must be deployed either in {jee-version} v4.x or v5.x. -However it is possible to adapt configuration files and run in any JMX container. - -[[_mux_source_code]] -== Source Code - -This section provides instructions on how to obtain and build the {this-platform} Diameter MUX from source code. - -[[_mux_release_source_building]] -=== Release Source Code Building - - -. Downloading the source code -+ -IMPORTANT: Subversion is used to manage its source code. -Instructions for using Subversion, including installation, can be found at http://svnbook.red-bean.com. -+ -Use SVN to checkout a specific release source. -The base URL is {this-trunk-source-code-url} . -Then add the specific release version, for example {project-version} . -+ -[source] ----- -[usr]$ git clone git@github.com:RestComm/jdiameter.git ----- - -. Building the source code -+ -IMPORTANT: Maven 3.2.5 (or higher) is used to build the release. -Instructions for using Maven2, including installation, can be found at http://maven.apache.org. -+ -Use Maven to build the deployable unit binary. -+ -[source] ----- - - [usr]$ cd - - [usr]$ mvn install ----- -+ -Once the process finishes you should have the SAR built. -If the [var]`JBOSS_HOME` environment variable is set, the will be deployed in the container after execution. - - -NOTE: By default {this-platform} Diameter MUX; deploys in the {jee-version} v5.x . -To change it, run [app]`maven` with the profile switch command: [parameter]`-Pjboss4`. - -[[_mux_trunk_source_building]] -=== Development Trunk Source Building - -Follow the <<_mux_release_source_building>> procedure, replacing the SVN source code URL with {this-trunk-source-code-url} . diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Source_Overview.adoc~ b/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Source_Overview.adoc~ deleted file mode 100644 index 009c125b6..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Source_Overview.adoc~ +++ /dev/null @@ -1,90 +0,0 @@ - -[[_mux_source_overview]] -= Diameter MUX Source Overview - -The Diameter MUX capabilities are defined by the `MBean` interface `org.mobicents.diameter.stack.DiameterStackMultiplexerMBean`. -This interface defines two types of methods: - -Management:: - Used by &MANAGEMENT.PLATFORM;console. - These methods are outside the scope of this documentation. - -Stack Accessors:: - Methods that allow the user to retrieve and use a wrapped stack. - -The methods below are of interest to a Diameter MUX user: - -[method]`public Stack getStack();`:: - Returns a stack wrapped by the multiplexer. - It is present as a convenience method, and the stack should only be changed directly by expert users. - -[method]`public void registerListener(DiameterListener listener, ApplicationId[] appIds) throws IllegalStateException;`:: - Registers a listener to be triggered when a message for a certain application ID is received. - -[method]`public void unregisterListener(DiameterListener listener);`:: - Removes the message listener. - -[method]`public DiameterStackMultiplexerMBean getMultiplexerMBean();`:: - Returns the actual instance of MUX. - -The listener interface is defined below: - -[source,java] ----- - -package org.mobicents.diameter.stack; - -import java.io.Serializable; - -import org.jdiameter.api.Answer; -import org.jdiameter.api.EventListener; -import org.jdiameter.api.NetworkReqListener; -import org.jdiameter.api.Request; - -public interface DiameterListener extends NetworkReqListener, Serializable, - EventListener -{ - -} ----- - -MUX can be used as follows: - -[source,java] ----- -public class DiameterActor implements DiameterListener -{ - private ObjectName diameterMultiplexerObjectName = null; - private DiameterStackMultiplexerMBean diameterMux = null; - - private synchronized void initStack() throws Exception { - this.diameterMultiplexerObjectName = - new ObjectName("diameter.mobicents:service=DiameterStackMultiplexer"); - - Object[] params = new Object[]{}; - String[] signature = new String[]{}; - - String operation = "getMultiplexerMBean"; - this.diameterMux=mbeanServer.invoke(this.diameterMultiplexerObjectName, operation, - params, signature); - - long acctAppIds = new long[]{19312L}; - long acctVendorIds = new long[]{193L}; - long authAppIds = new long[]{4L}; - long authVendorIds = new long[]{0L}; - List appIds = new ArrayList(); - for(int index = 0;index 1000){ - headerSize($scroll); - }else{ - logoSizeOnSmallScreens(); - } - - if($j(window).width() > 768){ - contentMenuPosition(); - } - contentMenuCheckLastSection(); - - $j('header:not(.stick_with_left_right_menu) .q_logo a').css('visibility','visible'); - /* set header and content menu position and appearance on page load - END */ - - initFullScreenTemplate(); - showHideVerticalMenu(); - initMasonryGallery(); - initLoadNextPostOnBottom(); -}); - -$j(window).load(function(){ - "use strict"; - - $j('.touch .main_menu li:has(div.second)').doubleTapToGo(); // load script to close menu on touch devices - initSmallImageBlogHeight(); - setDropDownMenuPosition(); - initDropDownMenu(); - initPortfolio(); - initPortfolioZIndex(); - initPortfolioSingleInfo(); - initTestimonials(); - initVideoBackgroundSize(); - initBlog(); - initBlogMasonryFullWidth(); - initQBlog(); - initPortfolioMasonry(); - initPortfolioMasonryFilter(); - initTabs(); - countClientsPerRow(); - animatedTextIconHeight(); - countAnimatedTextIconPerRow(); - initTitleAreaAnimation(); - setContentBottomMargin(); - footerWidth(); - if($j('nav.content_menu').length > 0){ - content_menu_position = $j('nav.content_menu').offset().top; - contentMenuPosition(); - } - contentMenuCheckLastSection(); - initQodeCarousel(); - initPortfolioSlider(); - initBlogSlider(); - initTabsActiveBorder(); - setActiveTabBorder(); - initImageHover(); - $j('header.stick_with_left_right_menu .q_logo a').css('visibility','visible'); - setMargingsForLeftAndRightMenu(); - initImageGallerySliderNoSpace(); - initVerticalSplitSlider(); - initParallax(); //has to be here on last place since some function is interfering with parallax - initQodeElementAnimationSkrollr(); - setTimeout(function(){ - checkAnchorOnScroll(); - checkAnchorOnLoad(); // it has to be after content top margin initialization to know where to scroll - checkHeaderStyleOnScroll(); //moved to window load because sections are not fully initialized on dom ready and calculations are wrong - if($j('.no-touch .carousel').length){skrollr_slider.refresh();} //in order to reload rest of scroll animation on same page after page loads - },700); //timeout is set because of some function that interferes with calculating -}); - -$j(window).scroll(function() { - "use strict"; - - $scroll = $j(window).scrollTop(); - - if($j(window).width() > 1000){ - headerSize($scroll); - } - - if($j(window).width() > 768){ - contentMenuPosition(); - } - contentMenuCheckLastSection(); - checkVerticalMenuTransparency(); - - $j('.touch .drop_down > ul > li').mouseleave(); - $j('.touch .drop_down > ul > li').blur(); -}); - -$j(window).resize(function() { - "use strict"; - - $window_width = $j(window).width(); - $window_height = $j(window).height(); - - //check paspartu width depending on window size - paspartu_width = $window_width < 1024 ? 0.02 : paspartu_width_init; - - if($j(window).width() > 1000){ - headerSize($scroll); - }else{ - logoSizeOnSmallScreens(); - } - initMessageHeight(); - initTestimonials(); - fitAudio(); - initSmallImageBlogHeight(); - initBlog(); - initBlogMasonryFullWidth(); - initQBlog(); - animatedTextIconHeight(); - countAnimatedTextIconPerRow(); - initVideoBackgroundSize(); - countClientsPerRow(); - setContentBottomMargin(); - footerWidth(); - calculateHeights(); - $j('.vertical_split_slider').height($window_height); //used for vertical split slider holder - initMasonryGallery(); - contentMinHeight(); - contentMinHeightWithPaspartu(); -}); - -/* -** Calculating header size on page load and page scroll -*/ -var sticky_animate; -function headerSize($scroll){ - "use strict"; - - if(($j('header.page_header').hasClass('scroll_top')) && ($j('header.page_header').hasClass('has_top')) && - ($j('header.page_header').hasClass('fixed') || $j('header.page_header').hasClass('fixed_hiding'))){ - if($scroll >= 0 && $scroll <= 34){ - $j('header.page_header').css('top',-$scroll); - $j('header.page_header').css('margin-top',0); - $j('.header_top').show(); - }else if($scroll > 34){ - $j('header.page_header').css('top','-34px'); - $j('header.page_header').css('margin-top',34); - $j('.header_top').hide(); - } - } - - //is scroll amount for sticky set on page? - if(typeof page_scroll_amount_for_sticky !== 'undefined') { - sticky_amount = page_scroll_amount_for_sticky; - } - - //do we have slider on the page? - else if($j('.carousel.full_screen').length) { - sticky_amount = $j('.carousel').height(); - } - - //take value from theme options - else { - sticky_amount = scroll_amount_for_sticky; - } - - if($j('header').hasClass('regular')){ -// $j('header .drop_down .second').css('top', header_height + header_bottom_border_weight +'px'); - if(header_height - logo_height >= 10){ - $j('.q_logo a').height(logo_height); - }else{ - $j('.q_logo a').height(header_height - 10); - } - $j('.q_logo a img').css('height','100%'); - } - - if($j('header.page_header').hasClass('fixed')){ - if($j('header.page_header').hasClass('scroll_top')){ - $top_header_height = 34; - }else{ - $top_header_height = 0; - } - - if((header_height - $scroll + $top_header_height >= min_header_height_scroll) && ($scroll >= $top_header_height)){ - $j('header.page_header').removeClass('scrolled'); - $j('header:not(.centered_logo.centered_logo_animate) nav.main_menu > ul > li > a').css('line-height', header_height - $scroll + $top_header_height+'px'); -// $j('header .drop_down .second').css('top', header_height + header_bottom_border_weight - ($scroll + $top_header_height)/8+'px'); - $j('header:not(.centered_logo.centered_logo_animate) .side_menu_button').css('height', header_height - $scroll + $top_header_height+'px'); - $j('header:not(.centered_logo.centered_logo_animate) .shopping_cart_inner').css('height', header_height - $scroll + $top_header_height+'px'); - $j('header:not(.centered_logo.centered_logo_animate) .logo_wrapper').css('height', header_height - $scroll + $top_header_height +'px'); - if(header_height - logo_height > 0){ - $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', logo_height +'px'); - }else{ - $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', (header_height - $scroll + $top_header_height - 10) +'px'); - } - - }else if($scroll < $top_header_height){ - $j('header.page_header').removeClass('scrolled'); - $j('header:not(.centered_logo.centered_logo_animate) nav.main_menu > ul > li > a').css('line-height', header_height+'px'); -// $j('header .drop_down .second').css('top', header_height + header_bottom_border_weight +'px'); - $j('header:not(.centered_logo.centered_logo_animate) .side_menu_button').css('height', header_height+'px'); - $j('header:not(.centered_logo.centered_logo_animate) .shopping_cart_inner').css('height', header_height+'px'); - $j('header:not(.centered_logo.centered_logo_animate) .logo_wrapper').css('height', header_height+'px'); - if(header_height - logo_height > 0){ - $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', logo_height +'px'); - }else{ - $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', (header_height-10)+'px'); - } - - }else if((header_height - $scroll + $top_header_height) < min_header_height_scroll){ - $j('header.page_header').addClass('scrolled'); - $j('header:not(.centered_logo.centered_logo_animate) nav.main_menu > ul > li > a').css('line-height', min_header_height_scroll+'px'); -// $j('header .drop_down .second').css('top', min_header_height_scroll + header_bottom_border_weight +'px'); - $j('header:not(.centered_logo.centered_logo_animate) .side_menu_button').css('height', min_header_height_scroll+'px'); - $j('header:not(.centered_logo.centered_logo_animate) .shopping_cart_inner').css('height', min_header_height_scroll+'px'); - $j('header:not(.centered_logo.centered_logo_animate) .logo_wrapper').css('height', min_header_height_scroll+'px'); - if(min_header_height_scroll - logo_height > 0){ - $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', logo_height +'px'); - }else{ - $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', (min_header_height_scroll-10)+'px'); - } - } - - // logo part - start // - - if($j('header.page_header').hasClass('centered_logo') && $j('header.page_header').hasClass('centered_logo_animate')){ - if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height >= min_header_height_scroll) && (logo_height > min_header_height_scroll - 10) && ($scroll >= $top_header_height)){ - $j('.q_logo a').height(header_height - $scroll + $top_header_height - 10); - }else if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height >= min_header_height_scroll) && (logo_height > min_header_height_scroll - 10) && ($scroll < $top_header_height)){ - $j('.q_logo a').height(header_height - 10); - }else if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height < min_header_height_scroll) && (logo_height > min_header_height_scroll - 10)){ - $j('.q_logo a').height(min_header_height_scroll - 10); - }else if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height < min_header_height_scroll) && (logo_height < min_header_height_scroll - 10)){ - $j('.q_logo a').height(logo_height); - }else if(($scroll + $top_header_height === 0) && (logo_height > header_height - 10)){ - $j('.q_logo a').height(logo_height); - }else{ - $j('.q_logo a').height(logo_height); - } - }else if($j('header.page_header').hasClass('centered_logo')) { - $j('.q_logo a').height(logo_height); - $j('.q_logo img').height('auto'); - }else{ - $j('.q_logo img').height('100%'); - } - // logo part - end // - - } - - if($j('header.page_header').hasClass('fixed_hiding')){ - - if($scroll < scroll_amount_for_fixed_hiding){ - $j('header.page_header').removeClass('scrolled'); - }else{ - $j('header.page_header').addClass('scrolled'); - } - - $j('.q_logo a').height(logo_height/2); //because of retina displays - $j('.q_logo img').height('100%'); - } - - if($j('header.page_header').hasClass('stick') || $j('header.page_header').hasClass('stick_with_left_right_menu')){ - if($scroll > sticky_amount){ - if(!$j('header.page_header').hasClass('sticky')){ - if($j('header.page_header').hasClass('has_top')){ - $top_header_height = 34; - }else{ - $top_header_height = 0; - } - var padding_top = $j('header.page_header').hasClass('centered_logo') ? $j('header.page_header').height() : header_height + $top_header_height; - if($j('header.page_header').hasClass('menu_bottom')){ - padding_top = header_height + 60; //60 is menu height for Sticky Advance header type - } - $j('header.page_header').addClass('sticky'); - $j('.content').css('padding-top',padding_top); - - window.clearTimeout(sticky_animate); - sticky_animate = window.setTimeout(function(){$j('header.page_header').addClass('sticky_animate');},100); - - - if(min_header_height_sticky - logo_height >= 10){ - $j('.q_logo a').height(logo_height); - }else{ - $j('.q_logo a').height(min_header_height_sticky - 10); - } - - if($j('header.page_header').hasClass('menu_bottom')){ - initDropDownMenu(); //recalculate dropdown menu position - } - } - - // logo part - start // - if(min_header_height_sticky - logo_height >= 10){ - $j('.q_logo a').height(logo_height); - }else{ - $j('.q_logo a').height(min_header_height_sticky - 10); - } - // logo part - end // - }else{ - if($j('header.page_header').hasClass('sticky')){ - $j('header').removeClass('sticky_animate'); - $j('header').removeClass('sticky'); - $j('.content').css('padding-top','0px'); - - if($j('header.page_header').hasClass('menu_bottom')){ - initDropDownMenu(); //recalculate dropdown menu position - } - } - - setMargingsForLeftAndRightMenu(); //need to set margins here since on sticky menu, logo is not visible on left/right logo - - // logo part - start // - if(!$j('header.page_header').hasClass('centered_logo')){ - if(header_height - logo_height >= 10){ - $j('.q_logo a').height(logo_height); - }else{ - $j('.q_logo a').height(header_height - 10); - } - }else{ - $j('.q_logo a').height(logo_height); - $j('.q_logo img').height('auto'); - } - $j('.q_logo a img').css('height','100%'); - // logo part - end // - } - } -} - -function setMargingsForLeftAndRightMenu(){ - "use strict"; - - if($j('header.page_header').hasClass('stick_with_left_right_menu') && !$j('header.page_header').hasClass('left_right_margin_set')){ - var logo_width = $j('.q_logo a img').width()/2; - if($scroll == 0 && logo_width != 0){ - $j('header.page_header').addClass('left_right_margin_set'); - } - $j('.logo_wrapper').width(logo_width*2); - $j('nav.main_menu.left_side > ul > li:last-child').css('margin-right',logo_width); - $j('nav.main_menu.right_side > ul > li:first-child').css('margin-left',logo_width); - - $j('.rtl nav.main_menu.left_side > ul > li:first-child').css('margin-right',logo_width); // add for rtl - $j('.rtl nav.main_menu.left_side > ul > li:last-child').css('margin-right',0); // add for rtl - $j('.rtl nav.main_menu.right_side > ul > li:last-child').css('margin-left',logo_width); // add for rtl - $j('.rtl nav.main_menu.right_side > ul > li:first-child').css('margin-left',0); // add for rtl - } -} - -/* -** Calculating logo size on smaller screens -*/ -function logoSizeOnSmallScreens(){ - "use strict"; - // 100 is height of header on small screens - - if((100 - 20 < logo_height)){ - $j('.q_logo a').height(100 - 20); - }else{ - $j('.q_logo a').height(logo_height); - } - $j('.q_logo a img').css('height','100%'); - - $j('header.page_header').removeClass('sticky_animate sticky'); - $j('.content').css('padding-top','0px'); - -} - -/* - ** Calculating minimal height for content - */ -function contentMinHeight(){ - "use strict"; - - if($j('header .header_bottom').length || $j('header .bottom_header').length){ - if($j('header .header_bottom').length){ var headerColorString = $j('header .header_bottom').css('background-color'); } - if($j('header .bottom_header').length){ var headerColorString = $j('header .bottom_header').css('background-color'); } - var headerTransparency = headerColorString.substring(headerColorString.indexOf('(') + 1, headerColorString.lastIndexOf(')')).split(/,\s*/)[3]; - var haeder_add = headerTransparency == undefined && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; - $j('body .content').css('min-height',$window_height - haeder_add - $j('footer:not(.uncover)').height()); - } -} - -/* - ** Calculating minimal height for content when paspartu is enabled - */ - -function contentMinHeightWithPaspartu(){ - "use strict"; - - if ($j('.paspartu_enabled').length) { - var content_height; - var paspartu_final_width_px = 0; - var paspartu_width_px = $window_width*paspartu_width; - var footer_height = $j('footer').height(); - - if ($j('.disable_footer').length){ - footer_height = 0; - } - - if ($j('.vertical_menu_enabled').length){ - if ($j('.paspartu_top').length && $j('.paspartu_middle_inner').length){ - paspartu_final_width_px += paspartu_width_px; - } - } - else { - if ($j('.paspartu_top').length){ - paspartu_final_width_px += paspartu_width_px; - } - } - if ($j('.paspartu_bottom').length || !$j('.disable_bottom_paspartu').length){ - paspartu_final_width_px += paspartu_width_px; - } - - if ($j('.vertical_menu_enabled').length){ - content_height = $window_height - paspartu_final_width_px - footer_height; - } - else { - if($j('header .header_bottom').length){ var headerColorString = $j('header .header_bottom').css('background-color'); } - if($j('header .bottom_header').length){ var headerColorString = $j('header .bottom_header').css('background-color'); } - var headerTransparency = headerColorString.substring(headerColorString.indexOf('(') + 1, headerColorString.lastIndexOf(')')).split(/,\s*/)[3]; - var header_height = headerTransparency == undefined && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; - content_height = $window_height - header_height - paspartu_final_width_px - footer_height; - } - - /*if($j('.content').length){ - $j('.content').css('min-height',content_height); - }*/ - } -} - -/* -** Initialize Qode Slider -*/ -var default_header_style; -function initQodeSlider(){ - "use strict"; - - var image_regex = /url\(["']?([^'")]+)['"]?\)/; - default_header_style = ""; - if($j('header.page_header').hasClass('light')){ default_header_style = 'light';} - if($j('header.page_header').hasClass('dark')){ default_header_style = 'dark';} - - if($j('.carousel').length){ - - var matrixArray = { zoom_center : '1.2, 0, 0, 1.2, 0, 0', zoom_top_left: '1.2, 0, 0, 1.2, -150, -150', zoom_top_right : '1.2, 0, 0, 1.2, 150, -150', zoom_bottom_left: '1.2, 0, 0, 1.2, -150, 150', zoom_bottom_right: '1.2, 0, 0, 1.2, 150, 150'}; - - // Function for translating image in slide - START // - (function ($) { - // - // regular expression for parsing out the matrix - // components from the matrix string - // - var matrixRE = /\([0-9epx\.\, \t\-]+/gi; - - // - // parses a matrix string of the form - // "matrix(n1,n2,n3,n4,n5,n6)" and - // returns an array with the matrix - // components - // - var parseMatrix = function (val) { - return val.match(matrixRE)[0].substr(1). - split(",").map(function (s) { - return parseFloat(s); - }); - }; - - // - // transform css property names with vendor prefixes; - // the plugin will check for values in the order the - // names are listed here and return as soon as there - // is a value; so listing the W3 std name for the - // transform results in that being used if its available - // - var transformPropNames = [ - "transform", - "-webkit-transform" - ]; - - var getTransformMatrix = function (el) { - // - // iterate through the css3 identifiers till we - // hit one that yields a value - // - var matrix = null; - transformPropNames.some(function (prop) { - matrix = el.css(prop); - return (matrix !== null && matrix !== ""); - }); - - // - // if "none" then we supplant it with an identity matrix so - // that our parsing code below doesn't break - // - matrix = (!matrix || matrix === "none") ? - "matrix(1,0,0,1,0,0)" : matrix; - return parseMatrix(matrix); - }; - - // - // set the given matrix transform on the element; note that we - // apply the css transforms in reverse order of how its given - // in "transformPropName" to ensure that the std compliant prop - // name shows up last - // - var setTransformMatrix = function (el, matrix) { - var m = "matrix(" + matrix.join(",") + ")"; - for (var i = transformPropNames.length - 1; i >= 0; --i) { - el.css(transformPropNames[i], m + ' rotate(0.01deg)'); - } - }; - - // - // interpolates a value between a range given a percent - // - var interpolate = function (from, to, percent) { - return from + ((to - from) * (percent / 100)); - }; - - $.fn.transformAnimate = function (opt) { - // - // extend the options passed in by caller - // - var options = { - transform: "matrix(1,0,0,1,0,0)" - }; - $.extend(options, opt); - - // - // initialize our custom property on the element - // to track animation progress - // - this.css("percentAnim", 0); - - // - // supplant "options.step" if it exists with our own - // routine - // - var sourceTransform = getTransformMatrix(this); - var targetTransform = parseMatrix(options.transform); - options.step = function (percentAnim, fx) { - // - // compute the interpolated transform matrix for - // the current animation progress - // - var $this = $(this); - var matrix = sourceTransform.map(function (c, i) { - return interpolate(c, targetTransform[i], - percentAnim); - }); - - // - // apply the new matrix - // - setTransformMatrix($this, matrix); - - // - // invoke caller's version of "step" if one - // was supplied; - // - if (opt.step) { - opt.step.apply(this, [matrix, fx]); - } - }; - - // - // animate! - // - return this.stop().animate({ percentAnim: 100 }, options); - }; - })(jQuery); - // Function for translating image in slide - END // - - $j('.carousel').each(function(){ - var $this = $j(this); - var mobile_header; - - var mobile_header = $j(window).width() < 1000 ? $j('header.page_header').height() : 0; - var header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') && $j('body.paspartu_on_top_fixed').length == 0 ? $j('header.page_header').height() : 0; - var paspartu_amount_with_top = $j('.paspartu_outer:not(.disable_top_paspartu)').length > 0 ? Math.round($window_width*paspartu_width + header_height_add_for_paspartu) : 0; - var paspartu_amount_with_bottom = $j('.paspartu_outer.paspartu_on_bottom_slider').length > 0 ? Math.round($window_width*paspartu_width) : 0; - var slider_graphic_coefficient; - var slider_title_coefficient; - var slider_subtitle_coefficient; - var slider_text_coefficient; - var slider_button_coefficient; - - var responsive_breakpoint_set = [1300,1000,768]; - if($this.hasClass('advanced_responsiveness')){ - responsive_breakpoint_set = [1600,1200,900,650,500,320]; - if($this.data('q_responsive_breakpoints')){ - if($this.data('q_responsive_breakpoints') == 'set2'){ - responsive_breakpoint_set = [1600,1300,1000,768,567,320]; - } - } - - var coefficients_graphic_array = $this.data('q_responsive_graphic_coefficients').split(','); - var coefficients_title_array = $this.data('q_responsive_title_coefficients').split(','); - var coefficients_subtitle_array = $this.data('q_responsive_subtitle_coefficients').split(','); - var coefficients_text_array = $this.data('q_responsive_text_coefficients').split(','); - var coefficients_button_array = $this.data('q_responsive_button_coefficients').split(','); - } - - //calculate heights for slider holder and slide item, depending on size, but only if slider is set to be responsive and not full screen - function setSliderHeight($this, $def_height){ - var slider_height = $def_height; - - if($this.hasClass('advanced_responsiveness')){ - //advanced responsiveness - if($window_width > responsive_breakpoint_set[0]){ - slider_height = $def_height; - }else if($window_width > responsive_breakpoint_set[1]){ - slider_height = $def_height * 0.75; - }else if($window_width > responsive_breakpoint_set[2]){ - slider_height = $def_height * 0.6; - }else if($window_width > responsive_breakpoint_set[3]){ - slider_height = $def_height * 0.55; - }else if($window_width <= responsive_breakpoint_set[3]){ - slider_height = $def_height * 0.45; - } - }else{ - //old way responsiveness - if($window_width > responsive_breakpoint_set[0]){ - slider_height = $def_height; - }else if($window_width > responsive_breakpoint_set[1]){ - slider_height = $def_height * 0.8; - }else if($window_width > responsive_breakpoint_set[2]){ - slider_height = $def_height * 0.7; - }else if($window_width <= responsive_breakpoint_set[2]){ - slider_height = $def_height * 1; - } - } - - $this.css({'height': (slider_height) + 'px'}); - $this.find('.qode_slider_preloader').css({'height': (slider_height) + 'px'}); - $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); - $this.find('.item').css({'height': (slider_height) + 'px'}); - } - - function resetSliderHeight($def_height){ - $this.css({'height': ($def_height) + 'px'}); - $this.find('.qode_slider_preloader').css({'height': ($def_height) + 'px'}); - $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); - $this.find('.item').css({'height': ($def_height) + 'px'}); - } - - function setSliderInitialElementsSize($item,i){ - - window["slider_graphic_width_" + i] = []; - window["slider_graphic_height_" + i] = []; - window["slider_svg_width_" + i] = []; - window["slider_svg_height_" + i] = []; - window["slider_title_" + i] = []; - window["slider_subtitle_" + i] = []; - window["slider_text_" + i] = []; - window["slider_button1_" + i] = []; - window["slider_button2_" + i] = []; - window["slider_separator_" + i] = []; - - //graphic size - window["slider_graphic_width_" + i].push(parseFloat($item.find('.thumb img').data("width"))); - window["slider_graphic_height_" + i].push(parseFloat($item.find('.thumb img').data("height"))); - window["slider_svg_width_" + i].push(parseFloat($item.find('.qode_slide-svg-holder svg').attr("width"))); - window["slider_svg_height_" + i].push(parseFloat($item.find('.qode_slide-svg-holder svg').attr("height"))); - - // font-size (0) - window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("font-size"))); - window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("font-size"))); - window["slider_text_" + i].push(parseFloat($item.find('.q_slide_text').css("font-size"))); - window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("font-size"))); - window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("font-size"))); - - // line-height (1) - window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("line-height"))); - window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("line-height"))); - window["slider_text_" + i].push(parseFloat($item.find('.q_slide_text').css("line-height"))); - window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("line-height"))); - window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("line-height"))); - - // letter-spacing (2) - window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("letter-spacing"))); - window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("letter-spacing"))); - window["slider_text_" + i].push(parseFloat($item.find('.q_slide_text').css("letter-spacing"))); - window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("letter-spacing"))); - window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("letter-spacing"))); - - // margin-bottom (3) - window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("margin-bottom"))); - window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("margin-bottom"))); - - // slider_button height(3), width(4), padding(5) - window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("height"))); - window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("height"))); - if(parseFloat($item.find('.qbutton:eq(0)').css("width")) != 0){ - window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("width"))); - }else{ - window["slider_button1_" + i].push(0); - } - if(parseFloat($item.find('.qbutton:eq(1)').css("width")) != 0){ - window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("width"))); - }else{ - window["slider_button2_" + i].push(0); - } - window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("padding-left"))); - window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("padding-left"))); - - // margin separator, margin top(0), margin bottom(1) - window["slider_separator_" + i].push(parseFloat($item.find('.separator').css("margin-top"))); - window["slider_separator_" + i].push(parseFloat($item.find('.separator').css("margin-bottom"))); - - } - - //calculate size for slider title, subtitle and text, depending on window size - function setSliderElementsSize($item,i){ - if($window_width > responsive_breakpoint_set[0]) { - slider_graphic_coefficient = coefficients_graphic_array[0]; - slider_title_coefficient = coefficients_title_array[0]; - slider_subtitle_coefficient = coefficients_subtitle_array[0]; - slider_text_coefficient = coefficients_text_array[0]; - slider_button_coefficient = coefficients_button_array[0]; - }else if($window_width > responsive_breakpoint_set[1]){ - slider_graphic_coefficient = coefficients_graphic_array[1]; - slider_title_coefficient = coefficients_title_array[1]; - slider_subtitle_coefficient = coefficients_subtitle_array[1]; - slider_text_coefficient = coefficients_text_array[1]; - slider_button_coefficient = coefficients_button_array[1]; - }else if($window_width > responsive_breakpoint_set[2]){ - slider_graphic_coefficient = coefficients_graphic_array[2]; - slider_title_coefficient = coefficients_title_array[2]; - slider_subtitle_coefficient = coefficients_subtitle_array[2]; - slider_text_coefficient = coefficients_text_array[2]; - slider_button_coefficient = coefficients_button_array[2]; - }else if($window_width > responsive_breakpoint_set[3]){ - slider_graphic_coefficient = coefficients_graphic_array[3]; - slider_title_coefficient = coefficients_title_array[3]; - slider_subtitle_coefficient = coefficients_subtitle_array[3]; - slider_text_coefficient = coefficients_text_array[3]; - slider_button_coefficient = coefficients_button_array[3]; - }else if ($window_width > responsive_breakpoint_set[4]) { - slider_graphic_coefficient = coefficients_graphic_array[4]; - slider_title_coefficient = coefficients_title_array[4]; - slider_subtitle_coefficient = coefficients_subtitle_array[4]; - slider_text_coefficient = coefficients_text_array[4]; - slider_button_coefficient = coefficients_button_array[4]; - }else if ($window_width > responsive_breakpoint_set[5]){ - slider_graphic_coefficient = coefficients_graphic_array[5]; - slider_title_coefficient = coefficients_title_array[5]; - slider_subtitle_coefficient = coefficients_subtitle_array[5]; - slider_text_coefficient = coefficients_text_array[5]; - slider_button_coefficient = coefficients_button_array[5]; - } - else{ - slider_graphic_coefficient = coefficients_graphic_array[6]; - slider_title_coefficient = coefficients_title_array[6]; - slider_subtitle_coefficient = coefficients_subtitle_array[6]; - slider_text_coefficient = coefficients_text_array[6]; - slider_button_coefficient = coefficients_button_array[6]; - } - - // letter-spacing decrease quicker - var slider_title_coefficient_letter_spacing = slider_title_coefficient; - var slider_subtitle_coefficient_letter_spacing = slider_subtitle_coefficient; - var slider_text_coefficient_letter_spacing = slider_text_coefficient; - if($window_width <= responsive_breakpoint_set[0]) { - slider_title_coefficient_letter_spacing = slider_title_coefficient/2; - slider_subtitle_coefficient_letter_spacing = slider_subtitle_coefficient/2; - slider_text_coefficient_letter_spacing = slider_text_coefficient/2; - } - - $item.find('.thumb').css({"width": Math.round(window["slider_graphic_width_" + i][0]*slider_graphic_coefficient) + 'px'}).css({"height": Math.round(window["slider_graphic_height_" + i][0]*slider_graphic_coefficient) + 'px'}); - $item.find('.qode_slide-svg-holder svg').css({"width": Math.round(window["slider_svg_width_" + i][0]*slider_graphic_coefficient) + 'px'}).css({"height": Math.round(window["slider_svg_height_" + i][0]*slider_graphic_coefficient) + 'px'}); - - $item.find('.q_slide_title').css({"font-size": Math.round(window["slider_title_" + i][0]*slider_title_coefficient) + 'px'}); - $item.find('.q_slide_title').css({"line-height": Math.round(window["slider_title_" + i][1]*slider_title_coefficient) + 'px'}); - $item.find('.q_slide_title').css({"letter-spacing": Math.round(window["slider_title_" + i][2]*slider_title_coefficient_letter_spacing) + 'px'}); - $item.find('.q_slide_title').css({"margin-bottom": Math.round(window["slider_title_" + i][3]*slider_title_coefficient) + 'px'}); - - $item.find('.q_slide_subtitle').css({"font-size": Math.round(window["slider_subtitle_" + i][0]*slider_subtitle_coefficient) + 'px'}); - $item.find('.q_slide_subtitle').css({"line-height": Math.round(window["slider_subtitle_" + i][1]*slider_subtitle_coefficient) + 'px'}); - $item.find('.q_slide_subtitle').css({"letter-spacing": Math.round(window["slider_subtitle_" + i][2]*slider_subtitle_coefficient_letter_spacing) + 'px'}); - $item.find('.q_slide_subtitle').css({"margin-bottom": Math.round(window["slider_subtitle_" + i][3]*slider_subtitle_coefficient) + 'px'}); - - $item.find('.q_slide_text').css({"font-size": Math.round(window["slider_text_" + i][0]*slider_text_coefficient) + 'px'}); - $item.find('.q_slide_text').css({"line-height": Math.round(window["slider_text_" + i][1]*slider_text_coefficient) + 'px'}); - $item.find('.q_slide_text').css({"letter-spacing": Math.round(window["slider_text_" + i][2]*slider_text_coefficient_letter_spacing) + 'px'}); - - $item.find('.qbutton:eq(0)').css({"font-size": Math.round(window["slider_button1_" + i][0]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(1)').css({"font-size": Math.round(window["slider_button2_" + i][0]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(0)').css({"line-height": Math.round(window["slider_button1_" + i][1]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(1)').css({"line-height": Math.round(window["slider_button2_" + i][1]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(0)').css({"letter-spacing": Math.round(window["slider_button1_" + i][2]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(1)').css({"letter-spacing": Math.round(window["slider_button2_" + i][2]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(0)').css({"height": Math.round(window["slider_button1_" + i][3]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(1)').css({"height": Math.round(window["slider_button2_" + i][3]*slider_button_coefficient) + 'px'}); - if(window["slider_button1_" + i][4] != 0) { - $item.find('.qbutton:eq(0)').css({"width": Math.round(window["slider_button1_" + i][4]*slider_button_coefficient) + 'px'}); - }else{ - $item.find('.qbutton:eq(0)').css({"width": 'auto'}); - } - if(window["slider_button2_" + i][4] != 0) { - $item.find('.qbutton:eq(1)').css({"width": Math.round(window["slider_button2_" + i][4]*slider_button_coefficient) + 'px'}); - }else{ - $item.find('.qbutton:eq(1)').css({"width": 'auto'}); - } - $item.find('.qbutton:eq(0)').css({"padding-left": Math.round(window["slider_button1_" + i][5]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(1)').css({"padding-left": Math.round(window["slider_button2_" + i][5]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(0)').css({"padding-right": Math.round(window["slider_button1_" + i][5]*slider_button_coefficient) + 'px'}); - $item.find('.qbutton:eq(1)').css({"padding-right": Math.round(window["slider_button2_" + i][5]*slider_button_coefficient) + 'px'}); - - $item.find('.separator').css({"margin-top": Math.round(window["slider_separator_" + i][0]*slider_title_coefficient) + 'px'}); - $item.find('.separator').css({"margin-bottom": Math.round(window["slider_separator_" + i][1]*slider_title_coefficient) + 'px'}); - - } - - function resetSliderElementsSize($item,i){ - $item.find('.thumb').css({"width": Math.round(window["slider_graphic_width_" + i][0]) + 'px'}).css({"height": Math.round(window["slider_graphic_height_" + i][0]) + 'px'}); - $item.find('.qode_slide-svg-holder svg').css({"width": Math.round(window["slider_svg_width_" + i][0]) + 'px'}).css({"height": Math.round(window["slider_svg_height_" + i][0]) + 'px'}); - - $item.find('.q_slide_title').css({"font-size": Math.round(window["slider_title_" + i][0]) + 'px'}); - $item.find('.q_slide_title').css({"line-height": Math.round(window["slider_title_" + i][1]) + 'px'}); - $item.find('.q_slide_title').css({"letter-spacing": Math.round(window["slider_title_" + i][2]) + 'px'}); - $item.find('.q_slide_title').css({"margin-bottom": Math.round(window["slider_title_" + i][3]) + 'px'}); - - $item.find('.q_slide_subtitle').css({"font-size": Math.round(window["slider_subtitle_" + i][0]) + 'px'}); - $item.find('.q_slide_subtitle').css({"line-height": Math.round(window["slider_subtitle_" + i][1]) + 'px'}); - $item.find('.q_slide_subtitle').css({"letter-spacing": Math.round(window["slider_subtitle_" + i][2]) + 'px'}); - $item.find('.q_slide_subtitle').css({"margin-bottom": Math.round(window["slider_subtitle_" + i][3]) + 'px'}); - - $item.find('.q_slide_text').css({"font-size": Math.round(window["slider_text_" + i][0]) + 'px'}); - $item.find('.q_slide_text').css({"line-height": Math.round(window["slider_text_" + i][1]) + 'px'}); - $item.find('.q_slide_text').css({"letter-spacing": Math.round(window["slider_text_" + i][2]) + 'px'}); - - $item.find('.qbutton:eq(0)').css({"font-size": Math.round(window["slider_button1_" + i][0]) + 'px'}); - $item.find('.qbutton:eq(1)').css({"font-size": Math.round(window["slider_button2_" + i][0]) + 'px'}); - $item.find('.qbutton:eq(0)').css({"line-height": Math.round(window["slider_button1_" + i][1]) + 'px'}); - $item.find('.qbutton:eq(1)').css({"line-height": Math.round(window["slider_button2_" + i][1]) + 'px'}); - $item.find('.qbutton:eq(0)').css({"letter-spacing": Math.round(window["slider_button1_" + i][2]) + 'px'}); - $item.find('.qbutton:eq(1)').css({"letter-spacing": Math.round(window["slider_button2_" + i][2]) + 'px'}); - $item.find('.qbutton:eq(0)').css({"height": Math.round(window["slider_button1_" + i][3]) + 'px'}); - $item.find('.qbutton:eq(1)').css({"height": Math.round(window["slider_button2_" + i][3]) + 'px'}); - if(window["slider_button1_" + i][4] != 0) { - $item.find('.qbutton:eq(0)').css({"width": Math.round(window["slider_button1_" + i][4]) + 'px'}); - }else{ - $item.find('.qbutton:eq(0)').css({"width": 'auto'}); - } - if(window["slider_button2_" + i][4] != 0) { - $item.find('.qbutton:eq(1)').css({"width": Math.round(window["slider_button2_" + i][4]) + 'px'}); - }else{ - $item.find('.qbutton:eq(1)').css({"width": 'auto'}); - } - $item.find('.qbutton:eq(0)').css({"padding-left": Math.round(window["slider_button1_" + i][5]) + 'px'}); - $item.find('.qbutton:eq(1)').css({"padding-left": Math.round(window["slider_button2_" + i][5]) + 'px'}); - $item.find('.qbutton:eq(0)').css({"padding-right": Math.round(window["slider_button1_" + i][5]) + 'px'}); - $item.find('.qbutton:eq(1)').css({"padding-right": Math.round(window["slider_button2_" + i][5]) + 'px'}); - - $item.find('.separator').css({"margin-top": Math.round(window["slider_separator_" + i][0]) + 'px'}); - $item.find('.separator').css({"margin-bottom": Math.round(window["slider_separator_" + i][1]) + 'px'}); - - } - - if($this.hasClass('full_screen')){ - $this.css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); - $this.find('.qode_slider_preloader').css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); - $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); - $this.find('.item').css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); - - if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ - if(!$j('body').hasClass('paspartu_on_top_fixed')){ - $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); - } - } - - if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ - $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); - } - - $j(window).resize(function() { - mobile_header = $j(window).width() < 1000 ? $j('header.page_header').height() : 0; - header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') && $j('body.paspartu_on_top_fixed').length == 0 ? $j('header.page_header').height() : 0; - paspartu_amount_with_top = $j('.paspartu_outer:not(.disable_top_paspartu)').length > 0 ? Math.round($window_width*paspartu_width + header_height_add_for_paspartu) : 0; - paspartu_amount_with_bottom = $j('.paspartu_outer.paspartu_on_bottom_slider').length > 0 ? Math.round($window_width*paspartu_width) : 0; - $this.css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); - $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); - $this.find('.item').css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); - - if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ - if(!$j('body').hasClass('paspartu_on_top_fixed')){ - $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); - } - } - if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ - $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); - } - - if($this.hasClass('advanced_responsiveness')){ - $this.find('.item').each(function(i){ - setSliderElementsSize($j(this),i); - }); - } - }); - }else if($this.hasClass('responsive_height')){ - var $def_height = $this.data('height'); - - $this.find('.qode_slider_preloader').css({'height': ($this.height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px', 'display': 'block'}); - if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ - if(!$j('body').hasClass('paspartu_on_top_fixed')){ - $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); - } - } - if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ - $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); - } - - setSliderHeight($this, $def_height); - - $j(window).resize(function() { - if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ - header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; - if(!$j('body').hasClass('paspartu_on_top_fixed')){ - $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); - } - } - if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ - $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); - } - - setSliderHeight($this, $def_height); - if($this.hasClass('advanced_responsiveness')){ - $this.find('.item').each(function(i){ - setSliderElementsSize($j(this),i); - }); - } - }); - }else { - $this.find('.qode_slider_preloader').css({'height': ($this.height() - mobile_header) + 'px', 'display': 'block'}); - $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); - if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ - if(!$j('body').hasClass('paspartu_on_top_fixed')){ - $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); - } - } - if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ - $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); - } - - if($this.hasClass('advanced_responsiveness')){ - $this.find('.item').each(function(i){ - setSliderInitialElementsSize($j(this),i); - setSliderElementsSize($j(this),i); - }); - } - $window_width < 1000 ? setSliderHeight($this, $def_height) : resetSliderHeight($def_height); - - $j(window).resize(function() { - if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ - header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; - if(!$j('body').hasClass('paspartu_on_top_fixed')){ - $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); - } - } - if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ - $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); - } - - if($window_width < 1000){ - setSliderHeight($this, $def_height); - if($this.hasClass('advanced_responsiveness')){ - $this.find('.item').each(function(i){ - setSliderElementsSize($j(this),i); - }); - } - }else{ - resetSliderHeight($def_height); - if($this.hasClass('advanced_responsiveness')){ - $this.find('.item').each(function(i){ - resetSliderElementsSize($j(this),i); - }); - } - } - }); - } - - if($j('body:not(.boxed):not(.vertical_menu_transparency):not(.vertical_menu_hidden):not(.page-template-landing_page-php)').hasClass('vertical_menu_enabled') && $j(window).width() > 1000){ - var paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) - $this.find('.carousel-inner').width($window_width - 260 - paspartu_add); - $j(window).resize(function() { - if($j(window).width() > 1000){ - paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) - $this.find('.carousel-inner').width($window_width - 260 - paspartu_add); - } else { - $this.find('.carousel-inner').css('width','100%'); - } - }); - } - - if($j('body:not(.boxed):not(.vertical_menu_transparency):not(.page-template-landing_page-php)').hasClass('vertical_menu_hidden') && $window_width > 1000){ - var paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) - $this.find('.carousel-inner').width($window_width - 40 - paspartu_add); - $j(window).resize(function() { - if($j(window).width() > 1000){ - paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) - $this.find('.carousel-inner').width($window_width - 40 - paspartu_add); - } else { - $this.find('.carousel-inner').css('width','100%'); - } - }); - } - - $j(window).scroll(function() { - if($scroll > ($this.height()+$j('header.page_header').height()) && $j(window).width() > 1000){ - $this.find('.carousel-inner, .carousel-indicators, button').hide(); - }else{ - $this.find('.carousel-inner, .carousel-indicators, button').show(); - } - }); - - var $slide_animation = $this.data('slide_animation'); - if($slide_animation === ""){ - $slide_animation = 6000; - } - - // function for setting prev/next numbers on arrows - var all_items_count = $j('div.item').length; - function setPrevNextNumbers(curr_item, all_items_count){ - if(curr_item == 1){ - $this.find('.left.carousel-control .prev').html(all_items_count); - $this.find('.right.carousel-control .next').html(curr_item + 1); - }else if(curr_item == all_items_count){ - $this.find('.left.carousel-control .prev').html(curr_item - 1); - $this.find('.right.carousel-control .next').html(1); - }else{ - $this.find('.left.carousel-control .prev').html(curr_item - 1); - $this.find('.right.carousel-control .next').html(curr_item + 1); - } - } - - function initSlider(){ - //set active class on first item - $this.find('.carousel-inner .item:first-child').addClass('active'); - checkSliderForHeaderStyle($j('.carousel .active'), $this.hasClass('header_effect')); - - if($this.hasClass('slider_thumbs')){ - // initial state of prev/next numbers - setPrevNextNumbers(1, all_items_count); - - //set prev and next thumb on load - if($this.find('.active').next('div').find('.image').length){ - src = image_regex.exec($this.find('.active').next('div').find('.image').attr('style')); - next_image = new Image(); - next_image.src = src[1]; - }else{ - next_image = $this.find('.active').next('div').find('> .video').clone(); - next_image.find('.video-overlay').remove(); - next_image.find('.video-wrap').width(170).height(95); - next_image.find('.mejs-container').width(170).height(95); - next_image.find('video').width(170).height(95); - } - $this.find('.right.carousel-control .img').html(next_image).find('img, div.video').addClass('old'); - - if($this.find('.carousel-inner .item:last-child .image').length){ - src = image_regex.exec($this.find('.carousel-inner .item:last-child .image').attr('style')); - prev_image = new Image(); - prev_image.src = src[1]; - }else{ - prev_image = $this.find('.carousel-inner .item:last-child > .video').clone(); - prev_image.find('.video-overlay').remove(); - prev_image.find('.video-wrap').width(170).height(95); - prev_image.find('.mejs-container').width(170).height(95); - prev_image.find('video').width(170).height(95); - } - $this.find('.left.carousel-control .img').html(prev_image).find('img, div.video').addClass('old'); - } - - if($this.hasClass('q_auto_start')){ - $this.carousel({ - interval: $slide_animation, - pause: false - }); - } else { - $this.carousel({ - interval: 0, - pause: false - }); - } - if($this.find('.item video').length){ - initVideoBackgroundSize(); - } - - if($this.hasClass('advanced_responsiveness') && ($this.hasClass('responsive_height') || $this.hasClass('full_screen'))){ - $this.find('.item').each(function (i) { - setSliderInitialElementsSize($j(this), i); - setSliderElementsSize($j(this), i); - }); - } - - //initiate image animation - if($j('.carousel-inner .item:first-child').hasClass('animate_image') && $window_width > 1000){ - $this.find('.carousel-inner .item.animate_image:first-child .image').transformAnimate({ - transform: "matrix("+matrixArray[$j('.carousel-inner .item:first-child').data('animate_image')]+")", - duration: 30000 - }); - } - } - - if($j('html').hasClass('touch')){ - if($this.find('.item:first-child .mobile-video-image').length > 0){ - src = image_regex.exec($this.find('.item:first-child .mobile-video-image').attr('style')); - if (src) { - var backImg = new Image(); - backImg.src = src[1]; - $j(backImg).load(function(){ - $j('.qode_slider_preloader').fadeOut(500); - initSlider(); - checkSVG($this); - }); - } - } - else{ - src = image_regex.exec($this.find('.item:first-child .image').attr('style')); - if (src) { - var backImg = new Image(); - backImg.src = src[1]; - $j(backImg).load(function(){ - $j('.qode_slider_preloader').fadeOut(500); - initSlider(); - checkSVG($this); - }); - } - } - } else { - if($this.find('.item:first-child video').length > 0){ - $this.find('.item:first-child video').get(0).addEventListener('loadeddata',function(){ - $j('.qode_slider_preloader').fadeOut(500); - initSlider(); - checkSVG($this); - }); - }else{ - src = image_regex.exec($this.find('.item:first-child .image').attr('style')); - if (src) { - var backImg = new Image(); - backImg.src = src[1]; - $j(backImg).load(function(){ - $j('.qode_slider_preloader').fadeOut(500); - initSlider(); - checkSVG($this); - }); - } - } - } - - $this.on('slide.bs.carousel', function () { - $this.addClass('in_progress'); - $this.find('.active .slider_content_outer').fadeTo(800,0); - }); - $this.on('slid.bs.carousel', function () { - $this.removeClass('in_progress'); - $this.find('.active .slider_content_outer').fadeTo(0,1); - checkSVG($this); - - // initiate image animation on active slide and reset all others - $j('div.item.animate_image .image').stop().css({'transform':'', '-webkit-transform':''}); - if($j('div.item.active').hasClass('animate_image') && $window_width > 1000){ - $j('div.item.animate_image.active .image').transformAnimate({ - transform: "matrix("+matrixArray[$j('div.item.animate_image.active').data('animate_image')]+")", - duration: 30000 - }); - } - - if($this.hasClass('slider_thumbs')){ - var curr_item = $j('div.item').index($j('div.item.active')[0]) + 1; - setPrevNextNumbers(curr_item, all_items_count); - - // prev thumb - if($this.find('.active').prev('div.item').length){ - if($this.find('.active').prev('div').find('.image').length){ - src = image_regex.exec($this.find('.active').prev('div').find('.image').attr('style')); - prev_image = new Image(); - prev_image.src = src[1]; - }else{ - prev_image = $this.find('.active').prev('div').find('> .video').clone(); - prev_image.find('.video-overlay').remove(); - prev_image.find('.video-wrap').width(170).height(95); - prev_image.find('.mejs-container').width(170).height(95); - prev_image.find('video').width(170).height(95); - } - $this.find('.left.carousel-control .img .old').fadeOut(300,function(){ - $j(this).remove(); - }); - $this.find('.left.carousel-control .img').append(prev_image).find('img, div.video').fadeIn(300).addClass('old'); - - }else{ - if($this.find('.carousel-inner .item:last-child .image').length){ - src = image_regex.exec($this.find('.carousel-inner .item:last-child .image').attr('style')); - prev_image = new Image(); - prev_image.src = src[1]; - }else{ - prev_image = $this.find('.carousel-inner .item:last-child > .video').clone(); - prev_image.find('.video-overlay').remove(); - prev_image.find('.video-wrap').width(170).height(95); - prev_image.find('.mejs-container').width(170).height(95); - prev_image.find('video').width(170).height(95); - } - $this.find('.left.carousel-control .img .old').fadeOut(300,function(){ - $j(this).remove(); - }); - $this.find('.left.carousel-control .img').append(prev_image).find('img, div.video').fadeIn(300).addClass('old'); - } - - // next thumb - if($this.find('.active').next('div.item').length){ - if($this.find('.active').next('div').find('.image').length){ - src = image_regex.exec($this.find('.active').next('div').find('.image').attr('style')); - next_image = new Image(); - next_image.src = src[1]; - }else{ - next_image = $this.find('.active').next('div').find('> .video').clone(); - next_image.find('.video-overlay').remove(); - next_image.find('.video-wrap').width(170).height(95); - next_image.find('.mejs-container').width(170).height(95); - next_image.find('video').width(170).height(95); - } - - $this.find('.right.carousel-control .img .old').fadeOut(300,function(){ - $j(this).remove(); - }); - $this.find('.right.carousel-control .img').append(next_image).find('img, div.video').fadeIn(300).addClass('old'); - - }else{ - if($this.find('.carousel-inner .item:first-child .image').length){ - src = image_regex.exec($this.find('.carousel-inner .item:first-child .image').attr('style')); - next_image = new Image(); - next_image.src = src[1]; - }else{ - next_image = $this.find('.carousel-inner .item:first-child > .video').clone(); - next_image.find('.video-overlay').remove(); - next_image.find('.video-wrap').width(170).height(95); - next_image.find('.mejs-container').width(170).height(95); - next_image.find('video').width(170).height(95); - } - $this.find('.right.carousel-control .img .old').fadeOut(300,function(){ - $j(this).remove(); - }); - $this.find('.right.carousel-control .img').append(next_image).find('img, div.video').fadeIn(300).addClass('old'); - } - } - }); - - $this.swipe( { - swipeLeft: function(event, direction, distance, duration, fingerCount){ $this.carousel('next'); }, - swipeRight: function(event, direction, distance, duration, fingerCount){ $this.carousel('prev'); }, - threshold:20 - }); - - }); - - if ($j('.no-touch .carousel').length) { - skrollr_slider = skrollr.init({ - edgeStrategy: 'set', - smoothScrolling: true, - forceHeight: false - }); - skrollr_slider.refresh(); - } - } -} - -function checkSliderForHeaderStyle($this, header_effect){ - "use strict"; - - var slide_header_style = ""; - var navigation_color = $this.data('navigation-color'); - if($this.hasClass('light')){ slide_header_style = 'light';} - if($this.hasClass('dark')){ slide_header_style = 'dark';} - - if( slide_header_style !== ""){ - if(header_effect){ - $j('header.page_header').removeClass('dark light').addClass(slide_header_style); - $j('aside.vertical_menu_area').removeClass('dark light').addClass(slide_header_style); - } - $j('.carousel .carousel-control, .carousel .carousel-indicators').removeClass('dark light').addClass(slide_header_style); - }else{ - if(header_effect){ - $j('header.page_header').removeClass('dark light').addClass(default_header_style); - $j('aside.vertical_menu_area').removeClass('dark light').addClass(default_header_style); - } - $j('.carousel .carousel-control, .carousel .carousel-indicators').removeClass('dark light').addClass(default_header_style); - } - - if(navigation_color !== undefined){ - $j('.carousel-control .thumb_holder .thumb_top, .carousel-indicators li').css('background-color',navigation_color); - $j('.carousel-control .prev_nav, .carousel-control .next_nav').css('border-color',navigation_color); - $j('.carousel-control .prev_nav i, .carousel-control .next_nav i').css('color',navigation_color); - }else{ - $j('.carousel-control .thumb_holder .thumb_top, .carousel-indicators li').css('background-color',''); - $j('.carousel-control .prev_nav, .carousel-control .next_nav').css('border-color',''); - $j('.carousel-control .prev_nav i, .carousel-control .next_nav i').css('color',''); - } -} - -/* - ** Set heights for qode carousel, portfolio slider and blog slider - */ -function calculateHeights(){ - if($j('.portfolio_slides').length){ - $j('.portfolio_slides').each(function(){ - $j(this).parents('.caroufredsel_wrapper').css({'height' : ($j(this).find('li.item').outerHeight()-3) + 'px'}); //3 is because of the white line bellow the slider - }); - } - - if($j('.qode_carousels .slides').length){ - $j('.qode_carousels .slides').each(function(){ - $j(this).parents('.caroufredsel_wrapper').css({'height' : ($j(this).find('li.item').outerHeight()) + 'px'}); - }); - } - - if($j('.blog_slides').length){ - $j('.blog_slides').each(function(){ - $j(this).parents('.caroufredsel_wrapper').css({'height' : ($j(this).find('li.item').outerHeight()-3) + 'px'}); - }); - } -} - -/* - ** Init Qode Carousel - */ -function initQodeCarousel(){ - "use strict"; - - if($j('.qode_carousels').length){ - $j('.qode_carousels').each(function(){ - var itemWidth = ($j(this).parents('.grid_section').length == 1) ? 170 : 315; - $j(this).find('.slides').carouFredSel({ - circular: true, - responsive: true, - scroll : { - items : 1, - duration : 1000, - pauseOnHover : false - }, - items: { - width: itemWidth, - visible: { - min: 1, - max: 6 - } - }, - auto: true, - mousewheel: false, - swipe: { - onMouse: true, - onTouch: true - } - - }).animate({'opacity': 1},1000); - }); - calculateHeights(); - } -} - -/* -** Init Portfolio Slider -*/ -function initPortfolioSlider(){ - "use strict"; - - if($j('.portfolio_slider').length){ - - $j('.portfolio_slider').each(function(){ - - var number_of_items; - var item_width_fw; - if(typeof $j(this).data('number_of_items') !== 'undefined') { - number_of_items = $j(this).data('number_of_items'); - } - else { - number_of_items = 'auto'; - } - - switch(number_of_items){ - case 4: - item_width_fw = 500; - break; - case 5: - item_width_fw = 350; - break; - default: - item_width_fw = 500; - break; - } - - var maxItems = ($j(this).parents('.grid_section').length == 1) ? 3 : number_of_items; - var itemWidth = ($j(this).parents('.grid_section').length == 1) ? 353 : item_width_fw; - - $j(this).find('.portfolio_slides').carouFredSel({ - circular: true, - responsive: true, - scroll: 1, - prev : { - button : function() { - return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-prev'); - } - }, - next : { - button : function() { - return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-next'); - } - }, - items: { - width: itemWidth, - visible: { - min: 1, - max: maxItems - } - }, - auto: false, - mousewheel: false, - swipe: { - onMouse: true, - onTouch: true - } - }).animate({'opacity': 1},1000); - }); - - calculateHeights(); - - $j('.portfolio_slider .flex-direction-nav a').click(function(e){ - e.preventDefault(); - e.stopImmediatePropagation(); - e.stopPropagation(); - }); - } -} - -/* - ** Init Blog Slider - */ -function initBlogSlider(){ - "use strict"; - - if($j('.blog_slider').length){ - - $j('.blog_slider').each(function(){ - - var blogs_shown; - var maxItems; - var itemWidth; - var autoPlay = false; - if(typeof $j(this).data('blogs_shown') !== 'undefined') { - blogs_shown = $j(this).data('blogs_shown'); - } - else if($j(this).hasClass('simple_slider')){ - blogs_shown = 1; - } - else{ - blogs_shown = 'auto'; - } - - if ($j(this).hasClass('simple_slider')) { - maxItems = 1; - itemWidth = 300; - autoPlay = false; - } - else { - maxItems = ($j(this).parents('.grid_section').length == 1) ? 3 : blogs_shown; - var itemWidthTemp; - - switch (blogs_shown) { - case 3: - itemWidthTemp = 667; - break; - case 4: - itemWidthTemp = 500; - break; - case 5: - itemWidthTemp = 400; - break; - case 6: - itemWidthTemp = 334; - break; - default: - itemWidthTemp = 500; - - break; - } - - itemWidth = ($j(this).parents('.grid_section').length == 1) ? 353 : itemWidthTemp; - } - - $j(this).find('.blog_slides').carouFredSel({ - circular: true, - responsive: true, - scroll: 1, - prev : { - button : function() { - return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-prev'); - } - }, - next : { - button : function() { - return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-next'); - } - }, - items: { - width: itemWidth, - visible: { - min: 1, - max: maxItems - } - }, - auto: autoPlay, - mousewheel: false, - swipe: { - onMouse: true, - onTouch: true - } - }).animate({'opacity': 1},1000); - }); - - calculateHeights(); - - $j('.blog_slider .flex-direction-nav a').click(function(e){ - e.preventDefault(); - e.stopImmediatePropagation(); - e.stopPropagation(); - }); - } -} - -/* -** Opening side menu on "menu button" click -*/ -var current_scroll; -function initSideMenu(){ - "use strict"; - - if ($j('body').hasClass('side_area_uncovered_from_content')) { - $j('.side_menu_button_wrapper a.side_menu_button_link, a.close_side_menu').click(function(e){ - e.preventDefault(); - $j('.side_menu').css({'right':'0'}); - if(!$j('.side_menu_button_wrapper a.side_menu_button_link').hasClass('opened')){ - $j('.side_menu').css({'visibility':'visible'}); - $j(this).addClass('opened'); - $j('body').addClass('right_side_menu_opened'); - current_scroll = $j(window).scrollTop(); - - $j(window).scroll(function() { - if(Math.abs($scroll - current_scroll) > 400){ - $j('body').removeClass('right_side_menu_opened'); - $j('.side_menu_button_wrapper a').removeClass('opened'); - var hide_side_menu = setTimeout(function(){ - $j('.side_menu').css({'visibility':'hidden'}); - clearTimeout(hide_side_menu); - },400); - } - }); - }else{ - $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); - $j('body').removeClass('right_side_menu_opened'); - var hide_side_menu = setTimeout(function(){ - $j('.side_menu').css({'visibility':'hidden'}); - clearTimeout(hide_side_menu); - },400); - } - }); - } - - if ($j('body').hasClass('side_menu_slide_with_content')) { - $j('.side_menu_button_wrapper a.side_menu_button_link, a.close_side_menu').click(function(e){ - e.preventDefault(); - - if(!$j('.side_menu_button_wrapper a.side_menu_button_link').hasClass('opened')){ - $j(this).addClass('opened'); - $j('body').addClass('side_menu_open'); - current_scroll = $j(window).scrollTop(); - $j(window).scroll(function() { - - if(Math.abs($scroll - current_scroll) > 400){ - $j('body').removeClass('side_menu_open'); - $j('.side_menu_button_wrapper a').removeClass('opened'); - } - }); - }else{//hamburger icon has class open on its click - $j('body').removeClass('side_menu_open'); - - - $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); - $j('body').removeClass('side_menu_open'); - - } - - e.stopPropagation(); - $j('.wrapper').click(function() { - e.preventDefault(); - $j('body').removeClass('side_menu_open'); - $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); - $j('body').removeClass('side_menu_open'); - }); - }); - } - - - if ($j('body').hasClass('side_menu_slide_from_right')) { - $j('.wrapper').prepend('
'); - $j('.side_menu_button_wrapper a.side_menu_button_link, a.close_side_menu').click(function(e){ - e.preventDefault(); - - if(!$j('.side_menu_button_wrapper a.side_menu_button_link').hasClass('opened')){ - $j(this).addClass('opened'); - $j('body').addClass('right_side_menu_opened'); - - $j(' .wrapper .cover').click(function() { - $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); - $j('body').removeClass('right_side_menu_opened'); - $j('.side_menu_button_wrapper a').removeClass('opened'); - }); - current_scroll = $j(window).scrollTop(); - $j(window).scroll(function() { - if(Math.abs($scroll - current_scroll) > 400){ - $j('body').removeClass('right_side_menu_opened'); - $j('.side_menu_button_wrapper a').removeClass('opened'); - } - }); - }else{ - $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); - $j('body').removeClass('right_side_menu_opened'); - } - }); - } -} - -function setDropDownMenuPosition(){ - "use strict"; - - var menu_items = $j(".drop_down > ul > li.narrow"); - menu_items.each( function(i) { - - var browser_width = $j(window).width()-16; // 16 is width of scroll bar - var boxed_layout = 1150; // boxed layout width - var menu_item_position = $j(menu_items[i]).offset().left; - var sub_menu_width = $j(menu_items[i]).find('.second .inner ul').width(); - var menu_item_from_left = 0; - if($j('body').hasClass('boxed')){ - menu_item_from_left = boxed_layout - (menu_item_position - (browser_width - boxed_layout)/2) + 17; // 17 is right padding between menu elements - } else { - menu_item_from_left = browser_width - menu_item_position + 17; // 17 is right padding between menu elements - } - var sub_menu_from_left; - - if($j(menu_items[i]).find('li.sub').length > 0){ - sub_menu_from_left = menu_item_from_left - sub_menu_width; - } - - if(menu_item_from_left < sub_menu_width || sub_menu_from_left < sub_menu_width){ - $j(menu_items[i]).find('.second').addClass('right'); - $j(menu_items[i]).find('.second .inner ul').addClass('right'); - } - }); -} - -function initDropDownMenu(){ - "use strict"; - - var menu_items = $j('.drop_down > ul > li'); - - menu_items.each( function(i) { - if ($j(menu_items[i]).find('.second').length > 0) { - if($j(menu_items[i]).hasClass('wide')){ - var dropdown = $j(this).find('.inner > ul'); - var dropdownPadding = parseInt(dropdown.css('padding-left').slice(0, -2)) + parseInt(dropdown.css('padding-right').slice(0, -2)); - - if(!$j(this).hasClass('left_position') && !$j(this).hasClass('right_position')){ - $j(this).find('.second').css('left',0); - } - - var tallest = 0; - $j(this).find('.second > .inner > ul > li').each(function() { - var thisHeight = $j(this).height(); - if(thisHeight > tallest) { - tallest = thisHeight; - } - }); - - $j(this).find('.second > .inner > ul > li').height(tallest); - - var row_number; - if($j(this).find('.second > .inner > ul > li').length > 4){ - row_number = 4; - }else{ - row_number = $j(this).find('.second > .inner > ul > li').length; - } - - var width = row_number*($j(this).find('.second > .inner > ul > li').outerWidth()); - $j(this).find('.second > .inner > ul').width(width); - - if(!$j(this).hasClass('wide_background')){ - if(!$j(this).hasClass('left_position') && !$j(this).hasClass('right_position')){ - var left_position = ($j(window).width() - 2 * ($j(window).width()-$j(this).find('.second').offset().left))/2 + (width+dropdownPadding)/2; - $j(this).find('.second').css('left',-left_position); - } - } else{ - if(!$j(this).hasClass('left_position') && !$j(this).hasClass('right_position')){ - var left_position = $j(this).find('.second').offset().left; - $j(this).find('.second').css('left',-left_position); - $j(this).find('.second').css('width',$j(window).width()); - } - } - } - - if(!menu_dropdown_height_set){ - $j(menu_items[i]).data('original_height', $j(menu_items[i]).find('.second').height() + 'px'); - $j(menu_items[i]).find('.second').height(0); - } - - if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { - $j(menu_items[i]).on("touchstart mouseenter",function(){ - $j(menu_items[i]).find('.second').css({'height': $j(menu_items[i]).data('original_height'), 'overflow': 'visible', 'visibility': 'visible', 'opacity': '1'}); - }).on("mouseleave", function(){ - $j(menu_items[i]).find('.second').css({'height': '0px','overflow': 'hidden', 'visivility': 'hidden', 'opacity': '0'}); - }); - - }else{ - var config = { - interval: 0, - over: function(){ - setTimeout(function() { - $j(menu_items[i]).find('.second').addClass('drop_down_start'); - $j(menu_items[i]).find('.second').stop().css({'height': $j(menu_items[i]).data('original_height')}); - }, 150); - }, - timeout: 150, - out: function(){ - $j(menu_items[i]).find('.second').stop().css({'height': '0px'}); - $j(menu_items[i]).find('.second').removeClass('drop_down_start'); - } - }; - $j(menu_items[i]).hoverIntent(config); - } - } - }); - $j('.drop_down ul li.wide ul li a, .drop_down ul li.narrow ul li a').on('click',function(){ - var $this = $j(this); - - if(!$this.next('ul').length && ($this.attr('href') !== "http://#") && ($this.attr('href') !== "#") && !$this.hasClass('no_link')) { - setTimeout(function() { - $this.mouseleave(); - }, 500); - } - }); - - menu_dropdown_height_set = true; -} - - -/* - ** Vertical menu toggle dropdown - */ - -function initVerticalMenu(){ - "use strict"; - - if ($j('.no-touch .vertical_menu_toggle').length) { - var menu_items = $j('.no-touch .vertical_menu_toggle > ul > li'); - var menu_items_2 = $j('.no-touch .vertical_menu_toggle ul li ul li'); - - menu_items.each( function(i) { - if($j(menu_items[i]).hasClass('has_sub')){ - var subitems_number = $j(menu_items[i]).find('.inner > ul > li').length; - $j(menu_items[i]).hoverIntent({ - over: function() { - $j(menu_items[i]).addClass('open'); - $j(menu_items[i]).find('.second').slideDown(subitems_number*40, 'easeInOutSine', function(){ - $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); - }); - - }, - out: function() { - //if(!$j(menu_items[i]).hasClass('active')){ - $j(menu_items[i]).removeClass('open'); - $j(menu_items[i]).find('.second').slideUp(subitems_number*40, 'easeInOutSine'); - //} - }, - timeout: 1000 - }); - } - }); - - menu_items_2.each( function(i) { - if($j(menu_items_2[i]).hasClass('menu-item-has-children')){ - var subitems_number = $j(menu_items_2[i]).find('ul > li').length; - $j(menu_items_2[i]).hoverIntent({ - over: function() { - $j(menu_items_2[i]).addClass('open'); - $j(menu_items_2[i]).find('ul').slideDown(subitems_number*40, 'easeInOutSine', function(){ - $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); - }); - }, - out: function() { - $j(menu_items_2[i]).removeClass('open'); - $j(menu_items_2[i]).find('ul').slideUp(subitems_number*40, 'easeInOutSine'); - }, - timeout: 1000 - }); - } - }); - } - else if ($j('.vertical_menu_on_click').length) { - var menu_items = $j('.vertical_menu_on_click > ul > li > a'); - var menu_items_2 = $j('.vertical_menu_on_click ul li ul li a'); - - menu_items.each( function(i) { - if($j(menu_items[i]).parent().hasClass('has_sub')){ - $j(menu_items[i]).on('tap click',function(e) { - e.preventDefault(); - if(!$j(this).parent().hasClass('open')) { - $j('.vertical_menu_on_click > ul > li').removeClass('open'); - $j('.vertical_menu_on_click > ul > li').find('.second').slideUp('fast'); - - $j(this).parent().addClass('open'); - $j(this).parent().find('.second').slideDown('slow', function () { - $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); - }); - }else{ - - $j(this).parent().removeClass('open'); - $j(this).parent().find('.second').slideUp('fast', function () { - $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); - }); - } - return false; - }); - } - }); - - menu_items_2.each( function(i) { - if($j(menu_items_2[i]).parent().hasClass('menu-item-has-children')){ - $j(menu_items_2[i]).on('tap click',function(e) { - e.preventDefault(); - if(!$j(this).parent().hasClass('open')) { - $j('.vertical_menu_on_click ul li ul li').removeClass('open'); - $j('.vertical_menu_on_click ul li ul li').find('ul').slideUp('fast'); - - $j(this).parent().addClass('open'); - $j(this).parent().find('ul').slideDown('slow', function () { - $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); - }); - }else{ - $j(this).parent().removeClass('open'); - $j(this).parent().find('ul').slideUp('fast', function () { - $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); - }); - } - return false; - }); - } - }); - } - else if ($j('.no-touch .vertical_menu_float').length){ - //show dropdown to content on menu item hover, link is available on menu item click - var menu_items = $j('.no-touch .vertical_menu_float > ul > li'); - var menu_items_2 = $j('.no-touch .vertical_menu_float ul li ul li'); - menu_items.each( function(i) { - if($j(menu_items[i]).hasClass('has_sub')){ - $j(menu_items[i]).hoverIntent({ - over: function() { - $j(menu_items[i]).addClass('open'); - $j(menu_items[i]).find('.second').addClass('vertical_menu_start'); - }, - out: function() { - //if(!$j(menu_items[i]).hasClass('active')){ - $j(menu_items[i]).removeClass('open'); - $j(menu_items[i]).find('.second').removeClass('vertical_menu_start'); - }, - timeout: 300 - }); - } - }); - - menu_items_2.each( function(i) { - if($j(menu_items_2[i]).hasClass('menu-item-has-children')){ - var subitems_number = $j(menu_items_2[i]).find('ul > li').length; - $j(menu_items_2[i]).hoverIntent({ - over: function() { - $j(menu_items_2[i]).addClass('open'); - $j(menu_items_2[i]).find('ul').addClass('vertical_submenu_start'); - }, - out: function() { - $j(menu_items_2[i]).removeClass('open'); - $j(menu_items_2[i]).find('ul').removeClass('vertical_submenu_start'); - }, - timeout: 300 - }); - } - }); - } - -} - -/* - ** Show/Hide Vertical menu for mobile - */ -function initVerticalMobileMenu(){ - "use strict"; - - if ($j('.vertical_menu_toggle').length) { - //register tap / click event for main menu item plus icon - $j('.touch .vertical_menu_toggle > ul > li.has_sub > a .plus').on('tap click', function(e){ - //first prevent event propagation and it's default behavior - e.stopPropagation(); - e.preventDefault(); - - //is dropdown for clicked item visible? - if($j(this).parent().next('div.second').is(":visible")){ - //if it is remove 'open' class and slide it up - $j(this).parents('.touch .vertical_menu_toggle > ul > li.has_sub').removeClass('open'); - $j(this).parent().next('div.second').slideUp(200); - } else { - //if it's not visible add 'open' class and slide it down - $j(this).parents('.touch .vertical_menu_toggle > ul > li.has_sub').addClass('open'); - $j(this).parent().next('div.second').slideDown(200); - } - }); - - //register tap / click event for second level main menu item plus icon - $j('.touch .vertical_menu_toggle ul li ul li > a .plus').on('tap click', function(e){ - //first prevent event propagation and it's default behavior - e.stopPropagation(); - e.preventDefault(); - - //is dropdown for clicked item visible? - if($j(this).parent().next('ul').is(":visible")){ - //if it is remove 'open' class and slide it up - $j(this).parents('.touch .vertical_menu_toggle ul li ul li').removeClass('open'); - $j(this).parent().next('ul').slideUp(200); - } else { - //if it's not visible add 'open' class and slide it down - $j(this).parents('.touch .vertical_menu_toggle ul li ul li').addClass('open'); - $j(this).parent().next('ul').slideDown(200); - } - }); - } - else if ($j('.vertical_menu_float').length){ - $j('.touch .vertical_menu_float > ul > li.has_sub > a .plus').on('tap click', function(e){ - //first prevent event propagation and it's default behavior - e.stopPropagation(); - e.preventDefault(); - - //is dropdown for clicked item visible? - if($j(this).parent().next('div.second').hasClass('vertical_menu_start')){ - //if it is remove 'open' class and 'vertical_menu_start' - $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').removeClass('open'); - $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').find('.second').removeClass('vertical_menu_start'); - } else { //if it's not visible add 'open' class and 'vertical_menu_start' - $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').addClass('open'); - $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').find('.second').addClass('vertical_menu_start'); - } - }); - //register tap / click event for second level main menu item plus icon - $j('.touch .vertical_menu_float ul li ul li > a .plus').on('tap click', function(e){ - //first prevent event propagation and it's default behavior - e.stopPropagation(); - e.preventDefault(); - - //is dropdown for clicked item visible? - if($j(this).parent().next('ul').hasClass('vertical_submenu_start')){ - //if it is remove 'open' class and slide it up - $j(this).parents('.touch .vertical_menu_float ul li ul li').removeClass('open'); - $j(this).parents('.touch .vertical_menu_float ul li ul li').find('ul').removeClass('vertical_submenu_start'); - - } else { - //if it's not visible add 'open' class and slide it down - $j(this).parents('.touch .vertical_menu_float ul li ul li').addClass('open'); - $j(this).parents('.touch .vertical_menu_float ul li ul li').find('ul').addClass('vertical_submenu_start'); - } - }); - } -} - -/* - ** Set transparency for left menu area - */ -function checkVerticalMenuTransparency(){ - if($scroll !== 0){ - $j('body.vertical_menu_transparency').removeClass('vertical_menu_transparency_on'); - }else{ - $j('body.vertical_menu_transparency').addClass('vertical_menu_transparency_on'); - } -} - -/* - ** Show/Hide hidden Vertical menu - */ -function showHideVerticalMenu(){ - - if($j('.vertical_menu_hidden').length) { - var vertical_menu = $j('aside.vertical_menu_area'); - var vertical_menu_bottom_logo = $j('.vertical_menu_area_bottom_logo'); - var hovered_flag = true; - - $j('.vertical_menu_hidden_button').on('click',function (e) { - e.preventDefault(); - if(hovered_flag) { - hovered_flag = false; - current_scroll = $j(window).scrollTop(); //current scroll is defined in front of "initSideMenu" function - vertical_menu.addClass('active'); - vertical_menu_bottom_logo.addClass('active'); - }else{ - hovered_flag = true; - vertical_menu.removeClass('active'); - vertical_menu_bottom_logo.removeClass('active'); - } - }); - - $j(window).scroll(function() { - if(Math.abs($scroll - current_scroll) > 400){ - hovered_flag = true; - vertical_menu.removeClass('active'); - vertical_menu_bottom_logo.removeClass('active'); - } - }); - - //take click outside vertical left/rifgt area and close it - (function() { - var Outclick, outclick, - _this = this; - Outclick = (function() { - Outclick.name = 'Outclick'; - function Outclick() { - this.objects = []; - } - Outclick.prototype.check = function(element, event) { - return !element.is(event.target) && element.has(event.target).length === 0; - }; - Outclick.prototype.trigger = function(e) { - var execute, - _this = this; - execute = false; - return $j.each(this.objects, function(index, el) { - if (_this.check(el.container, e)) { - if (el.related.length < 1) { - execute = true; - } else { - $j.each(el.related, function(index, relation) { - if (_this.check(relation, e)) { - return execute = true; - } else { - execute = false; - return false; - } - }); - } - if (execute) { - return el.callback.call(el.container); - } - } - }); - }; - return Outclick; - })(); - outclick = new Outclick; - $j.fn.outclick = function(options) { - var _this = this; - if (options == null) { - options = {}; - } - options.related || (options.related = []); - options.callback || (options.callback = function() { - return _this.hide(); - }); - return outclick.objects.push({ - container: this, - related: options.related, - callback: options.callback - }); - }; - $j(document).mouseup(function(e) { - return outclick.trigger(e); - }); - }).call(this); - $j(vertical_menu).outclick({ - callback: function() { - hovered_flag = true; - vertical_menu.removeClass('active'); - vertical_menu_bottom_logo.removeClass('active'); - } - }); - } -} - -/* -** Plugin for counter shortcode -*/ -(function($) { - "use strict"; - - $.fn.countTo = function(options) { - // merge the default plugin settings with the custom options - options = $.extend({}, $.fn.countTo.defaults, options || {}); - - // how many times to update the value, and how much to increment the value on each update - var loops = Math.ceil(options.speed / options.refreshInterval), - increment = (options.to - options.from) / loops; - - return $(this).each(function() { - var _this = this, - loopCount = 0, - value = options.from, - interval = setInterval(updateTimer, options.refreshInterval); - - function updateTimer() { - value += increment; - loopCount++; - $(_this).html(value.toFixed(options.decimals)); - - if (typeof(options.onUpdate) === 'function') { - options.onUpdate.call(_this, value); - } - - if (loopCount >= loops) { - clearInterval(interval); - value = options.to; - - if (typeof(options.onComplete) === 'function') { - options.onComplete.call(_this, value); - } - } - } - }); - }; - - $.fn.countTo.defaults = { - from: 0, // the number the element should start at - to: 100, // the number the element should end at - speed: 1000, // how long it should take to count between the target numbers - refreshInterval: 100, // how often the element should be updated - decimals: 0, // the number of decimal places to show - onUpdate: null, // callback method for every time the element is updated, - onComplete: null // callback method for when the element finishes updating - }; -})(jQuery); - -/* -** Counter from zero to defined number -*/ -function initToCounter(){ - "use strict"; - - if($j('.counter.zero').length){ - $j('.counter.zero').each(function() { - if(!$j(this).hasClass('executed')){ - $j(this).addClass('executed'); - if($j(this).parents('.vertical_split_slider').length){ - $j(this).parent().css('opacity', '1'); - var $max = parseFloat($j(this).text()); - $j(this).countTo({ - from: 0, - to: $max, - speed: 1500, - refreshInterval: 100 - }); - } - else{ - $j(this).appear(function() { - $j(this).parent().css('opacity', '1'); - var $max = parseFloat($j(this).text()); - $j(this).countTo({ - from: 0, - to: $max, - speed: 1500, - refreshInterval: 100 - }); - },{accX: 0, accY: -200}); - } - } - }); - } -} - -/* -** Counter with random effect -*/ -function initCounter(){ - "use strict"; - - if($j('.counter.random').length){ - $j('.counter.random').each(function() { - if(!$j(this).hasClass('executed')){ - $j(this).addClass('executed'); - if($j(this).parents('.vertical_split_slider').length){ - $j(this).parent().css('opacity', '1'); - $j(this).absoluteCounter({ - speed: 2000, - fadeInDelay: 1000 - }); - } - else{ - $j(this).appear(function() { - $j(this).parent().css('opacity', '1'); - $j(this).absoluteCounter({ - speed: 2000, - fadeInDelay: 1000 - }); - },{accX: 0, accY: -200}); - } - } - }); - } -} - -/* -** Countdown -*/ - -function initCountdown(){ - "use strict"; - if($j('.countdown').length){ - $j('.countdown').each(function(){ - - var countdownId = $j(this).attr('id'); - var $this = $j('#'+countdownId); - var year = 0; - var month = 0; - var day = 0; - var hour = 0; - var minute = 0; - var monthsLabel; - var monthLabel; - var daysLabel; - var dayLabel; - var hoursLabel; - var hourLabel; - var minutesLabel; - var minuteLabel; - var secondsLabel; - var secondLabel; - var tickf; - var timezone; - var digitfs; - var labelfs; - var color; - - if(typeof $this.data('year') !== 'undefined' && $this.data('year') !== false) { - year = $this.data('year'); - } - if(typeof $this.data('month') !== 'undefined' && $this.data('month') !== false) { - month = $this.data('month'); - } - if(typeof $this.data('day') !== 'undefined' && $this.data('day') !== false) { - day = $this.data('day'); - } - if(typeof $this.data('hour') !== 'undefined' && $this.data('hour') !== false) { - hour = $this.data('hour'); - } - if(typeof $this.data('minute') !== 'undefined' && $this.data('minute') !== false) { - minute = $this.data('minute'); - } - if(typeof $this.data('monthslabel') !== 'undefined' && $this.data('monthslabel') !== false) { - monthsLabel = $this.data('monthslabel'); - } - if(typeof $this.data('monthlabel') !== 'undefined' && $this.data('monthlabel') !== false) { - monthLabel = $this.data('monthlabel'); - } - if(typeof $this.data('dayslabel') !== 'undefined' && $this.data('dayslabel') !== false) { - daysLabel = $this.data('dayslabel'); - } - if(typeof $this.data('daylabel') !== 'undefined' && $this.data('daylabel') !== false) { - dayLabel = $this.data('daylabel'); - } - if(typeof $this.data('hourslabel') !== 'undefined' && $this.data('hourslabel') !== false) { - hoursLabel = $this.data('hourslabel'); - } - if(typeof $this.data('hourlabel') !== 'undefined' && $this.data('hourlabel') !== false) { - hourLabel = $this.data('hourlabel'); - } - if(typeof $this.data('minuteslabel') !== 'undefined' && $this.data('minuteslabel') !== false) { - minutesLabel = $this.data('minuteslabel'); - } - if(typeof $this.data('minutelabel') !== 'undefined' && $this.data('minutelabel') !== false) { - minuteLabel = $this.data('minuteLabel'); - } - if(typeof $this.data('secondslabel') !== 'undefined' && $this.data('secondslabel') !== false) { - secondsLabel = $this.data('secondslabel'); - } - if(typeof $this.data('secondlabel') !== 'undefined' && $this.data('secondlabel') !== false) { - secondLabel = $this.data('secondlabel'); - } - if(typeof $this.data('tickf') !== 'undefined' && $this.data('tickf') !== false) { - tickf = $this.data('tickf'); - } - if(typeof $this.data('timezone') !== 'undefined' && $this.data('timezone') !== false) { - timezone = $this.data('timezone'); - } - if(typeof $this.data('digitfs') !== 'undefined' && $this.data('digitfs') !== false) { - digitfs = $this.data('digitfs'); - } - if(typeof $this.data('labelfs') !== 'undefined' && $this.data('labelfs') !== false) { - labelfs = $this.data('labelfs'); - } - if(typeof $this.data('color') !== 'undefined' && $this.data('color') !== false) { - color = $this.data('color'); - } - - $this.countdown({ - until: new Date( year, month - 1, day, hour, minute, 44), - labels: ['Years', monthsLabel, 'Weeks', daysLabel, hoursLabel, minutesLabel, secondsLabel], - labels1: ['Year', monthLabel, 'Week', dayLabel, hourLabel, minuteLabel, secondLabel], - format: 'ODHMS', - timezone: timezone, - padZeroes: true, - significant: 0, - onTick: function(){ - if (digitfs !== 'undefined' && digitfs !== ''){ - $this.find('.countdown-amount').css('font-size',digitfs + 'px').css('line-height',digitfs + 'px'); - } - if (labelfs !== 'undefined' && labelfs !== ''){ - $this.find('.countdown-period').css('font-size',labelfs + 'px'); - } - if (color !== 'undefined' && color !== ''){ - $this.find('.countdown_separator').css('background-color',color); - } - } - }); - }); - } -} - -/* -** Horizontal progress bars shortcode -*/ -function initProgressBars(){ - "use strict"; - - if($j('.q_progress_bar').length){ - $j('.q_progress_bar').each(function() { - if($j(this).parents('.vertical_split_slider').length){ - initToCounterHorizontalProgressBar($j(this)); - var percentage = $j(this).find('.progress_content').data('percentage'); - $j(this).find('.progress_content').css('width', '0%'); - $j(this).find('.progress_content').animate({'width': percentage+'%'}, 1500); - $j(this).find('.progress_number_wrapper').css('width', '0%'); - $j(this).find('.progress_number_wrapper').animate({'width': percentage+'%'}, 1500); - } - else { - $j(this).appear(function() { - initToCounterHorizontalProgressBar($j(this)); - var percentage = $j(this).find('.progress_content').data('percentage'); - $j(this).find('.progress_content').css('width', '0%'); - $j(this).find('.progress_content').animate({'width': percentage+'%'}, 1500); - $j(this).find('.progress_number_wrapper').css('width', '0%'); - $j(this).find('.progress_number_wrapper').animate({'width': percentage+'%'}, 1500); - - - },{accX: 0, accY: -200}); - } - }); - } -} - -/* -** Counter for horizontal progress bars percent from zero to defined percent -*/ -function initToCounterHorizontalProgressBar($this){ - "use strict"; - - var percentage = parseFloat($this.find('.progress_content').data('percentage')); - if($this.find('.progress_number span').length) { - $this.find('.progress_number span').each(function() { - $j(this).parents('.progress_number_wrapper').css('opacity', '1'); - $j(this).countTo({ - from: 0, - to: percentage, - speed: 1500, - refreshInterval: 50 - }); - }); - } -} - -/* -** Unordered list animation effect -*/ -function initListAnimation(){ - "use strict"; - - if($j('.animate_list').length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.animate_list').each(function(){ - $j(this).appear(function() { - $j(this).find("li").each(function (l) { - var k = $j(this); - setTimeout(function () { - k.animate({ - opacity: 1, - top: 0 - }, 1500); - }, 100*l); - }); - },{accX: 0, accY: -200}); - }); - } -} - -/* -** Pie Chart shortcode -*/ -function initPieChart(){ - "use strict"; - - if($j('.q_percentage').length){ - $j('.q_percentage').each(function() { - - var $barColor = piechartcolor; - - if($j(this).data('active') !== ""){ - $barColor = $j(this).data('active'); - } - - var $trackColor = '#eeeeee'; - - if($j(this).data('noactive') !== ""){ - $trackColor = $j(this).data('noactive'); - } - - var $line_width = 10; - - if($j(this).data('linewidth') !== ""){ - $line_width = $j(this).data('linewidth'); - } - - var $size = 174; - - $j(this).appear(function() { - initToCounterPieChart($j(this)); - $j(this).parent().css('opacity', '1'); - - $j(this).easyPieChart({ - barColor: $barColor, - trackColor: $trackColor, - scaleColor: false, - lineCap: 'butt', - lineWidth: $line_width, - animate: 1500, - size: $size - }); - },{accX: 0, accY: -200}); - }); - } -} - -/* -** Pie Chart shortcode -*/ -function initPieChartWithIcon(){ - "use strict"; - - if($j('.q_percentage_with_icon').length){ - $j('.q_percentage_with_icon').each(function() { - - var $barColor = piechartcolor; - - if($j(this).data('active') !== ""){ - $barColor = $j(this).data('active'); - } - - var $trackColor = '#eeeeee'; - - if($j(this).data('noactive') !== ""){ - $trackColor = $j(this).data('noactive'); - } - - var $line_width = 10; - - if($j(this).data('linewidth') !== ""){ - $line_width = $j(this).data('linewidth'); - } - - var $size = 174; - - $j(this).appear(function() { - $j(this).parent().css('opacity', '1'); - $j(this).css('opacity', '1'); - $j(this).easyPieChart({ - barColor: $barColor, - trackColor: $trackColor, - scaleColor: false, - lineCap: 'butt', - lineWidth: $line_width, - animate: 1500, - size: $size - }); - },{accX: 0, accY: -200}); - }); - } -} - -/* -** Counter for pie chart number from zero to defined number -*/ -function initToCounterPieChart($this){ - "use strict"; - - $j($this).css('opacity', '1'); - var $max = parseFloat($j($this).find('.tocounter').text()); - $j($this).find('.tocounter').countTo({ - from: 0, - to: $max, - speed: 1500, - refreshInterval: 50 - }); -} - -/* -** Init Portfolio list and Portfolio Filter -*/ -function initPortfolio(){ - "use strict"; - - if($j('.projects_holder_outer:not(.masonry_with_space)').length){ - $j('.projects_holder_outer').each(function(){ - - $j('.filter_holder').each(function(){ - var filter_height = 0; - $j(this).find('li.filter').each(function(){ - filter_height += $j(this).height(); - }); - - $j(this).on('click',function(data){ - var $drop = $j(this), - $bro = $drop.siblings('.hidden'); - - if(!$drop.hasClass('expanded')){ - $drop.find('ul').css('z-index','1000'); - $drop.find('ul').height(filter_height+39); //36 is height of first default item + 1 border * 2 + 1 border on li - $drop.addClass('expanded'); - var label = $drop.find('.label span'); - label.text(label.attr('data-label')); - } else { - $drop.find('ul').height(36); - $drop.removeClass('expanded'); - - var $selected = $j(data.target), - ndx = $selected.index(); - - if($bro.length){ - $bro.find('option').removeAttr('selected').eq(ndx).attr('selected','selected').change(); - } - } - }); - }); - - $j('.filter_holder .filter').on('click',function(){ - var $this = $j(this).text(); - var dropLabels = $j('.filter_holder').find('.label span'); - dropLabels.each(function(){ - $j(this).text($this); - }); - }); - - var currentPortfolio = $j(this).find('.projects_holder'); - - if(currentPortfolio.hasClass('v1')){ - var timeArray= new Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25); - }else if(currentPortfolio.hasClass('v2')){ - var timeArray= new Array(1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20); - }else if(currentPortfolio.hasClass('v3')){ - var timeArray= new Array(1,2,3,2,3,4,3,4,5,4,5,6,5,6,7,6,7,8,7,8,9,8,9,10,9,10,11,10,11,12,11,12,13,12,13,14,13,14,15,14,15,16,15,16,17,16,17,18,17,18,19,18,19,20,19,20,21,20,21,22); - }else if(currentPortfolio.hasClass('v4')){ - var timeArray= new Array(1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7,5,6,7,8,6,7,8,9,7,8,9,10,8,9,10,11,9,10,11,12,10,11,12,13,11,12,13,14,12,13,14,15,13,14,15,16,14,15,16,17,15,16,17,18,16,17,18,19,17,18,19,20,18,19,20,21); - }else if(currentPortfolio.hasClass('v5')){ - var timeArray= new Array(1,2,3,4,5,2,3,4,5,6,3,4,5,6,7,4,5,6,7,8,5,6,7,8,9,6,7,8,9,10,7,8,9,10,11,8,9,10,11,12,9,10,11,12,13,10,11,12,13,14,11,12,13,14,15,12,13,14,15,16,13,14,15,16,17,14,15,16,17,18,15,16,17,18,19,20,16,17,18,19,20,17,18,19,20,21,18,19,20,21,22,19,20,21,22,23); - }else if(currentPortfolio.hasClass('v6')){ - var timeArray= new Array(1,2,3,4,5,6,2,3,4,5,6,7,3,4,5,6,7,8,4,5,6,7,8,9,5,6,7,8,9,10,6,7,8,9,10,11,7,8,9,10,11,12,8,9,10,11,12,13,9,10,11,12,13,14,10,11,12,13,14,15,11,12,13,14,15,16,12,13,14,15,16,17,13,14,15,16,17,18,14,15,16,17,18,19,15,16,17,18,19,20,16,17,18,19,20,21,17,18,19,20,21,22); - } - - currentPortfolio.mixitup({ - showOnLoad: 'all', - transitionSpeed: 600, - minHeight: 150, - onMixLoad: function(){ - $j('.projects_holder').addClass('hideItems'); - $j('.projects_holder article').css('visibility','visible'); - - if(currentPortfolio.hasClass('portfolio_one_by_one')) { - currentPortfolio.find('article').each(function(l) { - var currentPortfolioItem = $j(this); - if($j('.vertical_split_slider').length){ - var acc = 0; - }else{ - var acc = -150; - } - - setTimeout(function() { - currentPortfolioItem.addClass('show'); - }, 100*l); - }); - } - - if(currentPortfolio.hasClass('slide_from_left')) { - currentPortfolio.find('article').each(function(i) { - var currentPortfolioItem = $j(this); - - setTimeout(function() { - currentPortfolioItem.addClass('show'); - }, (Math.random() * 200)); - }); - } - - if(currentPortfolio.hasClass('slide_from_top')) { - currentPortfolio.find('article').each(function(i) { - var currentPortfolioItem = $j(this); - setTimeout(function() { - currentPortfolioItem.addClass('show'); - }, timeArray[i]*50); - }); - } - - if(currentPortfolio.hasClass('diagonal_fade')) { - currentPortfolio.find('article').each(function(i) { - var currentPortfolioItem = $j(this); - setTimeout(function() { - currentPortfolioItem.addClass('show'); - }, timeArray[i]*50); - }); - } - initParallax(); - }, - onMixEnd: function(){ - initParallax(); - } - }); - }); - } -} - -/* - ** Init z-index for portfolio items - */ -function initPortfolioZIndex(){ - "use strict"; - - if($j('.projects_holder_outer.portfolio_no_space').length){ - $j('.no_space.hover_text article').each(function(i){ - $j(this).css('z-index', i +10); - }); - } -} - -function initPortfolioMasonry(){ - "use strict"; - - if($j('.projects_masonry_holder, .masonry_with_space').length){ - - $j('.projects_masonry_holder, .masonry_with_space .projects_holder').each(function(){ - var $window = jQuery(window); - var $this = $j(this); - $this.waitForImages(function(){ - $this.animate({opacity:1}); - if($j('.projects_masonry_holder').length){ - resizeMasonry($this); - } - $this.isotope({ - resizable: false, - itemSelector: '.portfolio_masonry_item, .mix', - layoutMode: 'masonry' - }).isotope( 'layout' ); - - if($j('.projects_masonry_holder').length){ - setPortfolioMasZIndex(); - $window.resize(function() {resizeMasonry($this); setPortfolioMasZIndex();}); - } - - if($this.hasClass('portfolio_one_by_one')) { - $this.find('article').each(function(l) { - var $this = $j(this); - setTimeout(function() { - $this.addClass('show'); - }, 100*l); - }); - } - - if($this.hasClass('portfolio_fade_from_bottom')) { - $this.find('article').each(function(l) { - $j(this).appear(function() { - $j(this).addClass('show'); - },{accX: 0, accY: -150}); - }); - } - }); - }); - } -} - -var portfolio_width; -function resizeMasonry(container){ - var $window = jQuery(window); - - if($j('.full_width').length){ - if($j('body').hasClass('vertical_menu_enabled') && $window_width > 1000){ - portfolio_width = $window.innerWidth() - $j('.vertical_menu_area').innerWidth(); - }else { - portfolio_width = $window.innerWidth(); - } - }else{ - var closest_container = container.closest('.container_inner'); - if(closest_container.has('.column_inner').length) { - portfolio_width = container.closest('.column_inner').innerWidth(); - } else { - portfolio_width = closest_container.innerWidth(); - } - } - - container.width(portfolio_width); - - if(container.hasClass('gs4')){ - var $cols = 4; - if(portfolio_width <= 1000 && portfolio_width > 480){ - $cols = 2; - }else if(portfolio_width <= 480){ - $cols = 1; - } - - } else{ - var $cols = 5; - if(portfolio_width > 1600){ - $cols = 5; - }else if(portfolio_width <= 1600 && portfolio_width > 1200){ - $cols = 4; - }else if(portfolio_width <= 1200 && portfolio_width > 1000){ - $cols = 3; - }else if(portfolio_width <= 1000 && portfolio_width > 480){ - $cols = 2; - }else if(portfolio_width <= 480){ - $cols = 1; - } - } - - var largeItemHeight; - if(container.find('article[class*="default"]:first img').height()){ - largeItemHeight = container.find('article[class*="default"]:first img').height(); - }else if(container.find('article[class*="large_width"]:not(.large_width_height):first img').height()){ - largeItemHeight = container.find('article[class*="large_width"]:not(.large_width_height):first img').height(); - }else{ - largeItemHeight = (container.find('article[class*="large_width_height"]:first img').height()) ? (container.find('article[class*="large_width_height"]:first img').height())/2 : (container.find('article[class*="large_height"]:first img').height())/2; - } - var double = ($window.innerWidth() > 480) ? 2 : 1 ; - container.find('article[class*="large_width_height"] img, article[class*="large_height"] img').css('height',(largeItemHeight*double)); - - container.isotope({ - masonry: { columnWidth: portfolio_width / parseInt($cols)} - }); - - -} - - -function setPortfolioMasZIndex(){ - var $elemXPos = {}; - var $elemZIndex = {}; - - $j('.projects_masonry_holder article').each(function(){ - $elemXPos[$j(this).index()] = getPortfolioXPos($j(this).css('left')); - }); - - var $elemXPosArray = $j.map($elemXPos, function (value) { return value; }); - $elemXPosArray = cleanPortfolioMasXArray($elemXPosArray); - $elemXPosArray.sort(function(x,y){return x-y}); - - for(var i = 0; i < $elemXPosArray.length; i++){ - $elemZIndex[$elemXPosArray[i]] = i*10; - } - - $j.each($elemXPos,function(key,val){ - - var $zi; - var $bgd = val; - $j.each($elemZIndex,function(key,val){ - if($bgd == key) { - $zi = val; - } - }); - - $j('.projects_masonry_holder article:eq('+key+')').css('z-index',$zi); - }); -} - - -function cleanPortfolioMasXArray($elemXPosArray) { - var i; - var length = $elemXPosArray.length; - var $elemXPosOutArray = []; - var tmp = {}; - - for (i = 0; i < length; i++) { - tmp[$elemXPosArray[i]] = 0; - } - for (i in tmp) { - $elemXPosOutArray.push(i); - } - return $elemXPosOutArray; -} - -function getPortfolioXPos(css) { - //return css.substr(7, css.length - 8).split(', ')[4]; - return css.substr(0, css.length - 2); -} - -function initPortfolioMasonryFilter(){ - - "use strict"; - var portfolioIsotopeAnimation = null; - $j('.filter:first').addClass('current'); - $j('.filter').click(function(){ - - clearTimeout(portfolioIsotopeAnimation); - $j('.isotope, .isotope .isotope-item').css('transition-duration','0.8s'); - portfolioIsotopeAnimation = setTimeout(function(){ $j('.isotope, .isotope .isotope-item').css('transition-duration','0s'); },700); - - var selector = $j(this).attr('data-filter'); - $j('.projects_masonry_holder, .masonry_with_space .projects_holder').isotope({ filter: selector }); - - $j(".filter").removeClass("current"); - $j(this).addClass("current"); - - setTimeout(setPortfolioMasZIndex(),700); - - return false; - }); - -} - -function initServiceAnimation(){ - "use strict"; - - if($j(".fade_in_circle_holder").length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.fade_in_circle_holder').each(function(){ - $j(this).appear(function(){ - $j(this).addClass('animate_circle'); - },{accX: 0, accY: -200}); - }); - } -} - -function checkTitleToShowOrHide(){ - if($j('.title_outer.animate_title_area').length){ - var title_area_height = $j('.title_outer').data('height'); - if($scroll > $j('.title').height()){ - $j('.title_outer').css({'height':title_area_height, 'opacity':'1', 'overflow':'visible'}); - } - } -} - -/* -** Title area animation -*/ -function initTitleAreaAnimation(){ - if($j('.title_outer.animate_title_area').length){ - - var title_area_height = $j('.title_outer').data('height'); - if($j('.title_outer').hasClass('with_image')){ - title_area_height = $j('.image.responsive').height(); - } - if($scroll < $j('.title').height()){ - $j('.title_outer').animate({ height: title_area_height, opacity: 1}, 500, function(){ - $j(this).css({'overflow':'visible'}); - initPortfolioSingleInfo(); - if($j('nav.content_menu').length > 0){ - content_menu_position = $j('nav.content_menu').offset().top; - contentMenuPosition(); - } - }); - } - } -} - - -/* -** Title image with parallax effect -*/ -function initParallaxTitle(){ - "use strict"; - - if(($j('.title').length > 0) && ($j('.touch').length === 0)){ - - if($j('.title.has_fixed_background').length){ - - var $background_size_width = parseInt($j('.title.has_fixed_background').css('background-size').match(/\d+/)); - - var title_holder_height = $j('.title.has_fixed_background').height(); - var title_rate = (title_holder_height / 10000) * 7; - - var title_distance = $scroll - $j('.title.has_fixed_background').offset().top; - var title_bpos = -(title_distance * title_rate); - $j('.title.has_fixed_background').css({'background-position': 'center '+ (0+add_for_admin_bar) +'px' }); - if($j('.title.has_fixed_background').hasClass('zoom_out')){ - $j('.title.has_fixed_background').css({'background-size': $background_size_width-$scroll + 'px auto'}); - } - } - - $j(window).on('scroll', function() { - if($j('.title.has_fixed_background').length){ - - var title_distance = $scroll - $j('.title.has_fixed_background').offset().top; - - var title_bpos = -(title_distance * title_rate); - $j('.title.has_fixed_background').css({'background-position': 'center ' + (title_bpos+add_for_admin_bar) + 'px' }); - if($j('.title.has_fixed_background').hasClass('zoom_out')){ - $j('.title.has_fixed_background').css({'background-size': $background_size_width-$scroll + 'px auto'}); - } - } - }); - } -} - -/* - Plugin: jQuery Parallax - Version 1.1.3 - Author: Ian Lunn - Twitter: @IanLunn - Author URL: http://www.ianlunn.co.uk/ - Plugin URL: http://www.ianlunn.co.uk/plugins/jquery-parallax/ - - Dual licensed under the MIT and GPL licenses: - http://www.opensource.org/licenses/mit-license.php - http://www.gnu.org/licenses/gpl.html - */ - -(function( $ ){ - var $window = $(window); - var windowHeight = $window.height(); - - $window.resize(function () { - windowHeight = $window.height(); - }); - - $.fn.parallax = function(xpos, speedFactor, outerHeight) { - var $this = $(this); - var getHeight; - var firstTop; - var paddingTop = 0; - - //get the starting position of each element to have parallax applied to it - $this.each(function(){ - firstTop = $this.offset().top; - }); - - if (outerHeight) { - getHeight = function(jqo) { - return jqo.outerHeight(true); - }; - } else { - getHeight = function(jqo) { - return jqo.height(); - }; - } - - // setup defaults if arguments aren't specified - if (arguments.length < 1 || xpos === null) xpos = "50%"; - if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1; - if (arguments.length < 3 || outerHeight === null) outerHeight = true; - - // function to be called whenever the window is scrolled or resized - function update(){ - var pos = $window.scrollTop(); - - $this.each(function(){ - var $element = $(this); - var top = $element.offset().top; - var height = getHeight($element); - - // Check if totally above or totally below viewport - if (top + height < pos || top > pos + windowHeight) { - return; - } - - $this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px"); - }); - } - - $window.bind('scroll', update).resize(update); - update(); - }; -})(jQuery); - - -/* - ** Sections with parallax background image - */ -function initParallax(){ - "use strict"; - - if($j('.parallax_section_holder').length){ - $j('.parallax_section_holder').each(function() { - var speed = $j(this).data('speed')*0.4; - $j(this).parallax("50%", speed); - }); - } -} - -/* -** Smooth scroll functionality for Side Area -*/ -function initSideAreaScroll(){ - "use strict"; - - if($j('.side_menu').length){ - $j(".side_menu").niceScroll({ - scrollspeed: 60, - mousescrollstep: 40, - cursorwidth: 0, - cursorborder: 0, - cursorborderradius: 0, - cursorcolor: "transparent", - autohidemode: false, - horizrailenabled: false - }); - } -} - -/* - ** Smooth scroll functionality for Vertical Menu Area Toogle style - */ -function initVerticalAreaMenuScroll(){ - "use strict"; - - if($j('.vertical_menu_area.with_scroll').length){ - $j(".vertical_menu_area.with_scroll").niceScroll({ - scrollspeed: 60, - mousescrollstep: 40, - cursorwidth: 0, - cursorborder: 0, - cursorborderradius: 0, - cursorcolor: "transparent", - autohidemode: false, - horizrailenabled: false - }); - - } -} - -/* -** Load more portfolios -*/ -function loadMore(){ - "use strict"; - - var i = 1; - - $j('.load_more a').on('click', function(e) { - e.preventDefault(); - - var link = $j(this).attr('href'); - var $content = '.projects_holder'; - var $anchor = '.portfolio_paging .load_more a'; - var $next_href = $j($anchor).attr('href'); // Get URL for the next set of posts - var filler_num = $j('.projects_holder .filler').length; - - var load_more_holder = $j('.portfolio_paging'); - var loading_holder = $j('.portfolio_paging_loading'); - - load_more_holder.hide(); - loading_holder.show(); - - $j.get(link+'', function(data){ - $j('.projects_holder .filler').slice(-filler_num).remove(); - var $new_content = $j($content, data).wrapInner('').html(); // Grab just the content - $next_href = $j($anchor, data).attr('href'); // Get the new href - $j($content, data).waitForImages(function() { - - $j('article.mix:last').after($new_content); // Append the new content - - $j('.projects_holder article').css('visibility','visible'); - $j('article:not(.show)').each(function(l){ - $j(this).addClass('show'); - }); - - if($j('.masonry_with_space').length){ - $j('.masonry_with_space .projects_holder').isotope('reloadItems').isotope(); - }else{ - var min_height = $j('article.mix:first').height(); - $j('article.mix').css('min-height',min_height); - $j('.projects_holder').mixitup('remix','all'); - } - prettyPhoto(); - if($j('.load_more').attr('rel') > i) { - $j('.load_more a').attr('href', $next_href); // Change the next URL - } else { - $j('.load_more').remove(); - } - $j('.projects_holder .portfolio_paging:last').remove(); // Remove the original navigation - $j('article.mix').css('min-height',0); - - load_more_holder.show(); - loading_holder.hide(); - }); - - }); - i++; - }); -} - -/* -** Picture popup for portfolio lists and portfolio single -*/ -function prettyPhoto(){ - "use strict"; - - $j('a[data-rel]').each(function() { - $j(this).attr('rel', $j(this).data('rel')); - }); - - $j("a[rel^='prettyPhoto']").prettyPhoto({ - animation_speed: 'normal', /* fast/slow/normal */ - slideshow: false, /* false OR interval time in ms */ - autoplay_slideshow: false, /* true/false */ - opacity: 0.80, /* Value between 0 and 1 */ - show_title: true, /* true/false */ - allow_resize: true, /* Resize the photos bigger than viewport. true/false */ - horizontal_padding: 0, - default_width: 650, - default_height: 400, - counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */ - theme: 'pp_default', /* light_rounded / dark_rounded / light_square / dark_square / facebook */ - hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */ - wmode: 'opaque', /* Set the flash wmode attribute */ - autoplay: true, /* Automatically start videos: True/False */ - modal: false, /* If set to true, only the close button will close the window */ - overlay_gallery: false, /* If set to true, a gallery will overlay the fullscreen image on mouse over */ - keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */ - deeplinking: false, - social_tools: false - }); -} - -/* -** Show/Hide Mobile menu -*/ -function initMobileMenu(){ - "use strict"; - - $j(".mobile_menu_button > span").on('tap click', function(e){ - e.preventDefault(); - - if ($j(".mobile_menu > ul").is(":visible")){ - $j(".mobile_menu > ul").slideUp(200); - } else { - $j(".mobile_menu > ul").slideDown(200); - } - }); - - $j(".mobile_menu > ul > li.has_sub > span.mobile_arrow, .mobile_menu > ul > li.has_sub > h3, .mobile_menu > ul > li.has_sub > a[href*=#]").on('tap click', function(e){ - e.preventDefault(); - - if ($j(this).closest('li.has_sub').find("> ul.sub_menu").is(":visible")){ - $j(this).closest('li.has_sub').find("> ul.sub_menu").slideUp(200); - $j(this).closest('li.has_sub').removeClass('open_sub'); - } else { - $j(this).closest('li.has_sub').addClass('open_sub'); - $j(this).closest('li.has_sub').find("> ul.sub_menu").slideDown(200); - } - }); - - $j(".mobile_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > span.mobile_arrow, .mobile_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > h3, .mobile_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > a[href*=#]").on('tap click', function(e){ - e.preventDefault(); - - if ($j(this).parent().find("ul.sub_menu").is(":visible")){ - $j(this).parent().find("ul.sub_menu").slideUp(200); - $j(this).parent().removeClass('open_sub'); - } else { - $j(this).parent().addClass('open_sub'); - $j(this).parent().find("ul.sub_menu").slideDown(200); - } - }); - - $j(".mobile_menu ul li > a, .q_logo a").on('click', function(){ - - if(($j(this).attr('href') !== "http://#") && ($j(this).attr('href') !== "#")){ - $j(".mobile_menu > ul").slideUp(); - } - }); -} - -/* -** Init flexslider for portfolio single -*/ -function initFlexSlider(){ - "use strict"; - $j('.flexslider').each(function(){ - var interval = 8000; - if(typeof $j(this).data('interval') !== 'undefined' && $j(this).data('interval') !== false) { - interval = parseFloat($j(this).data('interval')) * 1000; - } - - var slideshow = true; - if(interval === 0) { - slideshow = false; - } - - var animation = 'slide'; - if(typeof $j(this).data('flex_fx') !== 'undefined' && $j(this).data('flex_fx') !== false) { - animation = $j(this).data('flex_fx'); - } - - $j(this).flexslider({ - animationLoop: true, - controlNav: false, - useCSS: false, - pauseOnAction: true, - pauseOnHover: true, - slideshow: slideshow, - animation: animation, - prevText: "
", - nextText: "
", - animationSpeed: 600, - slideshowSpeed: interval, - start: function(){ - setTimeout(function(){$j(".flexslider").fitVids();},100); - } - }); - - $j('.flex-direction-nav a').click(function(e){ - e.preventDefault(); - e.stopImmediatePropagation(); - e.stopPropagation(); - }); - }); -} - -/* -** Init fitVideo function for responsive video files -*/ -function fitVideo(){ - "use strict"; - - $j(".portfolio_images").fitVids(); - $j(".video_holder").fitVids(); - $j(".format-video .post_image").fitVids(); - $j(".format-video .q_masonry_blog_post_image").fitVids(); -} - -/* -** Function for follow portfolio single descripton -*/ -var $scrollHeight; -function initPortfolioSingleInfo(){ - "use strict"; - - var $sidebar = $j(".portfolio_single_follow"); - if($j(".portfolio_single_follow").length > 0){ - - var offset = $sidebar.offset(); - $scrollHeight = $j(".portfolio_container").height(); - var $scrollOffset = $j(".portfolio_container").offset(); - var $window = $j(window); - - var $headerHeight = parseInt($j('header.page_header').css('height'), 10); - - $window.scroll(function() { - if($window.width() > 960){ - if ($window.scrollTop() + $headerHeight + 3 > offset.top) { - if ($window.scrollTop() + $headerHeight + $sidebar.height() + 24 < $scrollOffset.top + $scrollHeight) { - - $sidebar.stop().animate({ - marginTop: $window.scrollTop() - offset.top + $headerHeight - }); - } else { - $sidebar.stop().animate({ - marginTop: $scrollHeight - $sidebar.height() - 24 - }); - } - } else { - $sidebar.stop().animate({ - marginTop: 0 - }); - } - }else{ - $sidebar.css('margin-top',0); - } - }); - } -} - -/* -** Init tabs shortcodes -*/ -function initTabs(){ - "use strict"; - if($j('.q_tabs').length){ - $j('.q_tabs').appear(function() { - $j('.q_tabs').css('visibility', 'visible'); - },{accX: 0, accY: -100}); - var $tabsNav = $j('.tabs-nav'); - var $tabsNavLis = $tabsNav.children('li'); - $tabsNav.each(function() { - var $this = $j(this); - $this.next().children('.tab-content').stop(true,true).hide().first().show(); - $this.children('li').first().addClass('active').stop(true,true).show(); - }); - $tabsNavLis.on('click', function(e) { - var $this = $j(this); - $this.siblings().removeClass('active').end().addClass('active'); - $this.parent().next().children('.tab-content').stop(true,true).hide().siblings( $this.find('a').attr('href') ).fadeIn(); - e.preventDefault(); - }); - } -} - -/* - ** Init accordion and toogle shortcodes - */ -function initAccordion() { - "use strict"; - - if($j(".q_accordion_holder").length){ - $j(".q_accordion_holder").appear(function() { - $j(".q_accordion_holder").css('visibility', 'visible'); - },{accX: 0, accY: -100}); - - if ($j(".accordion").length) { - $j(".accordion").accordion({ - animate: "swing", - collapsible: true, - active: false, - icons: "", - heightStyle: "content", - activate: function(event, ui) { - initParallax(); - } - }); - - //define custom options for each accordion - $j(".accordion").each(function() { - var activeTab = parseInt($j(this).data('active-tab')); - if(activeTab !== "") { - activeTab = activeTab - 1; // - 1 because active tab is set in 0 index base - $j(this).accordion('option', 'active', activeTab); - } - var borderRadius = parseInt($j(this).data('border-radius')); - - if(borderRadius !== "") { - $j(this).find('.accordion_mark').css('border-radius', borderRadius+"px"); - } - var collapsible = ($j(this).data('collapsible') == 'yes') ? true : false; - $j(this).accordion('option', 'collapsible', collapsible); - $j(this).accordion('option', 'collapsible', collapsible); - }); - } - $j(".toggle").addClass("accordion ui-accordion ui-accordion-icons ui-widget ui-helper-reset") - .find(".title-holder") - .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom") - .hover(function() { - $j(this).toggleClass("ui-state-hover"); - }) - .click(function() { - $j(this) - .toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom") - .next().toggleClass("ui-accordion-content-active").slideToggle(400); - return false; - }) - .next() - .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom") - .hide(); - - $j(".toggle").each(function() { - var activeTab = parseInt($j(this).data('active-tab')); - if(activeTab !== "" && activeTab >= 1) { - activeTab = activeTab - 1; // - 1 because active tab is set in 0 index base - $j(this).find('.ui-accordion-content').eq(activeTab).show(); - $j(this).find('.ui-accordion-header').eq(activeTab).addClass('ui-state-active'); //set active accordion header - } - - }); - } -} - -/* -** Function to enable link in accordion -*/ -function initAccordionContentLink(){ - "use strict"; - - if($j(".accordion").length){ - $j('.accordion_holder .accordion_inner .accordion_content a').click(function(){ - if($j(this).attr('target') === '_blank'){ - window.open($j(this).attr('href'),'_blank'); - }else{ - window.open($j(this).attr('href'),'_self'); - } - return false; - }); - } -} - -/* -** Init testimonials shortcode -*/ -function initTestimonials(){ - "use strict"; - - if($j('.testimonials_carousel').length){ - $j('.testimonials_carousel').each(function(){ - var interval = 5000; - if(typeof $j(this).data('auto-rotate-slides') !== 'undefined' && $j(this).data('auto-rotate-slides') !== false) { - interval = parseFloat($j(this).data('auto-rotate-slides')) * 1000; - } - - var slideshow = true; - if(interval === 0) { - slideshow = false; - } - - var animation = 'fade'; - if(typeof $j(this).data('animation-type') !== 'undefined' && $j(this).data('animation-type') !== false) { - animation = $j(this).data('animation-type'); - } - - var directionNav = true; - if(typeof $j(this).data('show-navigation') !== 'undefined') { - directionNav = $j(this).data('show-navigation') == 'no' ? false : true; - } - - var animationSpeed = 600; - if(typeof $j(this).data('animation-speed') !== 'undefined' && $j(this).data('animation-speed') !== false) { - animationSpeed = $j(this).data('animation-speed'); - } - - $j(this).flexslider({ - animationLoop: true, - controlNav: false, - directionNav: directionNav, - useCSS: false, - pauseOnAction: true, - pauseOnHover: false, - slideshow: slideshow, - animation: animation, - itemMargin: 25, - minItems: 1, - maxItems: 1, - animationSpeed: animationSpeed, - slideshowSpeed: interval, - start: function(slider){ - initParallax(); - } - }); - }); - - } -} - -/* -** Function to close message shortcode -*/ -function initMessages(){ - "use strict"; - - if($j('.q_message').length){ - $j('.q_message').each(function(){ - $j(this).find('.close').click(function(e){ - e.preventDefault(); - $j(this).parent().parent().fadeOut(500); - }); - }); - } -} -/* -** Init Element Animations -*/ -function initElementsAnimation(){ - "use strict"; - - if($j(".element_from_fade").length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.element_from_fade').each(function(){ - var $this = $j(this); - - $this.appear(function() { - $this.addClass('element_from_fade_on'); - },{accX: 0, accY: -100}); - }); - } - - if($j(".element_from_left").length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.element_from_left').each(function(){ - var $this = $j(this); - - $this.appear(function() { - $this.addClass('element_from_left_on'); - },{accX: 0, accY: -100}); - }); - } - - if($j(".element_from_right").length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.element_from_right').each(function(){ - var $this = $j(this); - - $this.appear(function() { - $this.addClass('element_from_right_on'); - },{accX: 0, accY: -100}); - }); - } - - if($j(".element_from_top").length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.element_from_top').each(function(){ - var $this = $j(this); - - $this.appear(function() { - $this.addClass('element_from_top_on'); - },{accX: 0, accY: -100}); - }); - } - - if($j(".element_from_bottom").length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.element_from_bottom').each(function(){ - var $this = $j(this); - - $this.appear(function() { - $this.addClass('element_from_bottom_on'); - },{accX: 0, accY: -100}); - }); - } - - if($j(".element_transform").length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.element_transform').each(function(){ - var $this = $j(this); - - $this.appear(function() { - $this.addClass('element_transform_on'); - },{accX: 0, accY: -100}); - }); - } -} - -/* -** Init audio player for blog layout -*/ -function fitAudio(){ - "use strict"; - - $j('audio.blog_audio').mediaelementplayer({ - audioWidth: '100%' - }); -} - -/* -** Init masonry layout for blog template -*/ -function initBlog() { - "use strict"; - - if($j('.blog_holder.masonry').length) { - var width_blog = $j(this).closest('.container_inner').width(); - if($j('.blog_holder.masonry').closest(".column_inner").length) { - width_blog = $j('.blog_holder.masonry').closest(".column_inner").width(); - } - $j('.blog_holder.masonry').width(width_blog); - var $container = $j('.blog_holder.masonry'); - - $container.waitForImages(function() { - setTimeout(function() { - $container.isotope({ - itemSelector: 'article', - resizable: false, - masonry: {columnWidth: '.blog_holder_grid_sizer', gutter: '.blog_holder_grid_gutter'} - }); - - $j('.blog_holder.masonry').animate({opacity: "1"}, 500); - }, 400); - }); - - $j('.filter').click(function() { - var selector = $j(this).attr('data-filter'); - $container.isotope({filter: selector}); - return false; - }); - - if($container.hasClass('masonry_infinite_scroll')) { - $container.infinitescroll({ - navSelector: '.blog_infinite_scroll_button span', - nextSelector: '.blog_infinite_scroll_button span a', - itemSelector: 'article', - loading: { - finishedMsg: finished_text, - msgText: loading_text - } - }, - // call Isotope as a callback - function(newElements) { - $container.isotope('appended', $j(newElements)); - fitVideo(); - fitAudio(); - initFlexSlider(); - setTimeout(function() { - $j('.blog_holder.masonry').isotope('layout'); - }, 400); - } - ); - } else if($container.hasClass('masonry_load_more')) { - - - var i = 1; - $j('.blog_load_more_button a').off('click tap').on('click tap', function(e) { - e.preventDefault(); - - var load_more_holder = $j('.blog_load_more_button'); - var load_more_loading = $j('.blog_load_more_button_loading'); - load_more_holder.hide(); - load_more_loading.show(); - - var link = $j(this).attr('href'); - var $content = '.masonry_load_more'; - var $anchor = '.blog_load_more_button a'; - var $next_href = $j($anchor).attr('href'); - $j.get(link + '', function(data) { - var $new_content = $j($content, data).wrapInner('').html(); - $next_href = $j($anchor, data).attr('href'); - $container.append($j($new_content)).isotope('reloadItems').isotope({sortBy: 'original-order'}); - fitVideo(); - fitAudio(); - initFlexSlider(); - setTimeout(function() { - $j('.blog_holder.masonry').isotope('layout'); - }, 400); - - load_more_holder.show(); - load_more_loading.hide(); - - if($j('.blog_load_more_button span').attr('rel') > i) { - $j('.blog_load_more_button a').attr('href', $next_href); // Change the next URL - } else { - $j('.blog_load_more_button').remove(); - } - }); - i++; - }); - - } - } -} - -/* - ** Init full width masonry layout for blog template - */ -function initBlogMasonryFullWidth(){ - "use strict"; - - if($j('.masonry_full_width').length){ - var width_blog = $j('.full_width_inner').width(); - - $j('.masonry_full_width').width(width_blog); - var $container = $j('.masonry_full_width'); - - $j('.filter').click(function(){ - var selector = $j(this).attr('data-filter'); - $container.isotope({ filter: selector }); - return false; - }); - if( $container.hasClass('masonry_infinite_scroll')){ - $container.infinitescroll({ - navSelector : '.blog_infinite_scroll_button span', - nextSelector : '.blog_infinite_scroll_button span a', - itemSelector : 'article', - loading: { - finishedMsg: finished_text, - msgText : loading_text - } - }, - // call Isotope as a callback - function( newElements ) { - $container.isotope( 'appended', $j( newElements ) ); - fitVideo(); - fitAudio(); - initFlexSlider(); - - setTimeout(function() { - $j('.blog_holder.masonry_full_width').isotope( 'layout'); - }, 400); - } - ); - }else if($container.hasClass('masonry_load_more')){ - - - var i = 1; - $j('.blog_load_more_button a').off('click tap').on('click tap', function(e) { - e.preventDefault(); - - var link = $j(this).attr('href'); - var $content = '.masonry_load_more'; - var $anchor = '.blog_load_more_button a'; - var $next_href = $j($anchor).attr('href'); - $j.get(link+'', function(data){ - var $new_content = $j($content, data).wrapInner('').html(); - $next_href = $j($anchor, data).attr('href'); - $container.append( $j( $new_content) ).isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' }); - fitVideo(); - fitAudio(); - initFlexSlider(); - - setTimeout(function() { - $j('.blog_holder.masonry_full_width').isotope( 'layout'); - }, 400); - - if($j('.blog_load_more_button span').attr('rel') > i) { - $j('.blog_load_more_button a').attr('href', $next_href); // Change the next URL - } else { - $j('.blog_load_more_button').remove(); - } - - }); - i++; - }); - - } - - $container.waitForImages(function() { - setTimeout(function() { - $container.isotope({ - itemSelector: 'article', - resizable: false, - masonry: { columnWidth: '.blog_holder_grid_sizer',gutter: '.blog_holder_grid_gutter'} - }); - - $j('.masonry_full_width').animate({opacity: "1"}, 500); - }, 400); - }); - } -} - -/* - ** Min height for smaall image blog - */ -function initSmallImageBlogHeight(){ - "use strict"; - - if($j('.blog_small_image').length){ - $j('article').each(function() { - $j(this).find('.post_text_inner').css('min-height', $j(this).find('.post_image').height() - 46); //46 is top and bottom padding - }); - } -} - - -/* -** Init masonry layout for blog masonry shortcode -*/ -function initQBlog(){ - "use strict"; - - if($j('.q_masonry_blog').length){ - $j('.q_masonry_blog').each(function() { - var width_blog; - width_blog = $j(this).parents('.container_inner').width(); - if($j('.full_width').length && $j(this).parents('.grid_section').length == 0){ - width_blog = $j('.full_width').width(); - }else{ - if($j(this).parents(".column_inner").length) { - width_blog = $j(this).parents(".column_inner").width(); - } - } - - $j(this).width(width_blog); - var $container = $j(this); - var $cols = 3; - if($j('.full_width').length && $j(this).parents('.grid_section').length == 0){ - if($container.width() < 480) { - $cols = 1; - } else if($container.width() <= 703) { - $cols = 2; - } else if($container.width() <= 920) { - $cols = 3; - } else if($container.width() <= 1320) { - $cols = 4; - } else{ - $cols = 5; - } - } else{ - if($container.width() < 420) { - $cols = 1; - } else if($container.width() <= 805) { - $cols = 2; - } - } - $container.isotope({ - itemSelector: 'article', - resizable: false, - masonry: { columnWidth: $j('.q_masonry_blog').width() / $cols } - }); - $j(window).resize(function(){ - - if($j('.full_width').length && $j(this).parents('.grid_section').length == 0){ - if($container.width() < 480) { - $cols = 1; - } else if($container.width() <= 703) { - $cols = 2; - } else if($container.width() <= 920) { - $cols = 3; - } else if($container.width() <= 1320) { - $cols = 4; - } else { - $cols = 5; - } - } else{ - if($container.width() < 420) { - $cols = 1; - } else if($container.width() <= 785) { - $cols = 2; - } else { - $cols = 3; - } - } - $container.isotope({ - masonry: { columnWidth: $container.width() / $cols} - }); - }); - $j(this).animate({opacity: "1"}, 500); - }); - } -} - -/* -** Init progress bar with icon -*/ -var timeOuts = []; -function initProgressBarsIcon(){ - "use strict"; - - if($j('.q_progress_bars_icons_holder').length){ - $j('.q_progress_bars_icons_holder').each(function() { - var $this = $j(this); - $this.appear(function() { - $this.find('.q_progress_bars_icons').css('opacity','1'); - $this.find('.q_progress_bars_icons').each(function() { - var number = $j(this).find('.q_progress_bars_icons_inner').data('number'); - var size = $j(this).find('.q_progress_bars_icons_inner').data('size'); - - if(size !== ""){ - $j(this).find('.q_progress_bars_icons_inner.custom_size .bar').css({'width': size+'px','height':size+'px'}); - $j(this).find('.q_progress_bars_icons_inner.custom_size .bar .fa-stack').css({'font-size': size/2+'px'}); - } - - var bars = $j(this).find('.bar'); - - bars.each(function(i){ - if(i < number){ - var time = (i + 1)*150; - timeOuts[i] = setTimeout(function(){ - $j(bars[i]).addClass('active'); - },time); - } - }); - }); - },{accX: 0, accY: -200}); - }); - } -} - -(function( $ ){ - "use strict"; - - var $window = $(window); - $.fn.masonryParallax = function(speedFactor, outerHeight, startPosition) { - var $this = $(this); - var getHeight; - var firstTop; - var startPositionAdd = 0; - - //get the starting position of element to have parallax applied to it - firstTop = $this.offset().top; - - //get the height element - if (outerHeight) { - getHeight = function(jqo) { - return jqo.outerHeight(true); - }; - } else { - getHeight = function(jqo) { - return jqo.height(); - }; - } - - //get type so elements could take it's initial position - if(startPosition != 0){ - startPositionAdd = startPosition; - } - - // setup defaults if arguments aren't specified - if (arguments.length < 1 || speedFactor === null) speedFactor = 0.1; - if (arguments.length < 2 || outerHeight === null) outerHeight = true; - - // function to be called whenever the window is scrolled or resized - var top = $this.offset().top; - var height = getHeight($this); - function update(){ - // Check if totally above or totally below viewport - if (top + height < $scroll || top > $scroll + $window_height) { - return; - } - $this.css('transform', 'translate3d(0px, '+ (Math.round((firstTop - height - $scroll) * speedFactor + startPositionAdd)) +'px, 0px)'); - } - - $window.bind('scroll', update).resize(update); - update(); - }; -})(jQuery); - -/** - * Masonry gallery, init masonry and resize pictures in grid - */ -function initMasonryGallery(){ - "use strict"; - - resizeMasonryGallery($j('.grid-sizer').width()); - - if($j('.masonry_gallery_holder').length){ - - $j('.masonry_gallery_holder').each(function(){ - var $this = $j(this); - $this.waitForImages(function(){ - $this.animate({opacity:1}); - $this.isotope({ - itemSelector: '.masonry_gallery_item', - masonry: { - columnWidth: '.grid-sizer' - } - }); - - $this.find('.masonry_gallery_item.parallax_item').each(function(i){ - $j(this).masonryParallax($this.data('parallax_item_speed'), true, $this.data('parallax_item_offset')); - - }); - }); - }); - $j(window).resize(function(){ - resizeMasonryGallery($j('.grid-sizer').width()); - $j('.masonry_gallery_holder').isotope('reloadItems'); - }); - } -} - -function resizeMasonryGallery(size){ - "use strict"; - - var rectangle_portrait = $j('.masonry_gallery_holder .rectangle_portrait'); - var rectangle_landscape = $j('.masonry_gallery_holder .rectangle_landscape'); - var square_big = $j('.masonry_gallery_holder .square_big'); - var square_small = $j('.masonry_gallery_holder .square_small'); - - rectangle_portrait.css('height', 2*size); - if (window.innerWidth < 600) { - rectangle_landscape.css('height', size/2); - } - else { - rectangle_landscape.css('height', size); - } - square_big.css('height', 2*size); - if (window.innerWidth < 600) { - square_big.css('height', square_big.width()); - } - square_small.css('height', size); -} - -/* -** Init more facts shortcode -*/ -function initMoreFacts(){ - "use strict"; - - if($j('.more_facts_holder').length){ - $j('.more_facts_holder').each(function(){ - var $this = $j(this); - - var $more_label = 'More Facts'; - - if($j(this).find('.more_facts_button').data('morefacts') !== ""){ - $more_label = $j(this).find('.more_facts_button').data('morefacts'); - } - - var $less_label = 'Less Facts'; - - if($j(this).find('.more_facts_button').data('lessfacts') !== ""){ - $less_label = $j(this).find('.more_facts_button').data('lessfacts'); - } - - var height = $this.find('.more_facts_inner').height() + 70; - - var speed; - if(height > 0 && height < 601){ - speed = 800; - } else if(height > 600 && height < 1201){ - speed = 1500; - } else{ - speed = 2100; - } - $this.find('.more_facts_outer').css({'height':'0px','display':'none','opacity':'0'}); - - $this.find('.more_facts_button').on("mouseenter",function(){ - $j(this).css('color',$j(this).data('hovercolor')); - }).on("mouseleave",function() { - if(!$this.find('.more_facts_outer').is(':visible')){ - $j(this).css('color',$j(this).data('color')); - } - }); - - $this.find('.more_facts_button').click(function(){ - if(!$this.find('.more_facts_outer').is(':visible')){ - $this.find('.more_facts_fake_arrow').fadeIn(speed); - $this.addClass('more_fact_opened'); - $j(this).parent().parent().find('.more_facts_outer').css({'display':'block','opacity':'1'}).stop().animate({'height': height+30}, speed, function() { - if($j('.parallax_section_holder').length) { - initParallax(); - } - }); - $j(this).find('.more_facts_button_text').text($less_label); - $j(this).find('.more_facts_button_arrow').addClass('rotate_arrow'); - } else { - $this.find('.more_facts_fake_arrow').fadeOut(speed); - $j(this).parent().parent().find('.more_facts_outer').stop().animate({'height': '0px'}, speed,function(){ - $j(this).css({'display':'none','opacity':'0'}); - - if(!$this.find('.more_facts_button').is(":hover")){$this.find('.more_facts_button').css('color',$this.find('.more_facts_button').data('color'));} - $this.removeClass('more_fact_opened'); - - if($j('.parallax_section_holder').length) { - initParallax(); - } - }); - $j(this).find('.more_facts_button_text').text($more_label); - $j(this).find('.more_facts_button_arrow').removeClass('rotate_arrow'); - } - }); - }); - } -} - -/* -** Replace plceholder -*/ -function placeholderReplace(){ - "use strict"; - - $j('#contact-form [placeholder]').focus(function() { - var input = $j(this); - if (input.val() === input.attr('placeholder')) { - if (this.originalType) { - this.type = this.originalType; - delete this.originalType; - } - input.val(''); - input.removeClass('placeholder'); - } - }).blur(function() { - var input = $j(this); - if (input.val() === '') { - if (this.type === 'password') { - this.originalType = this.type; - this.type = 'text'; - } - input.addClass('placeholder'); - input.val(input.attr('placeholder')); - } - }).blur(); - - $j('#contact-form [placeholder]').parents('form').submit(function () { - $j(this).find('[placeholder]').each(function () { - var input = $j(this); - if (input.val() === input.attr('placeholder')) { - input.val(''); - } - }); - }); -} - -function totop_button(a) { - "use strict"; - - var b = $j("#back_to_top"); - b.removeClass("off on"); - if (a === "on") { b.addClass("on"); } else { b.addClass("off"); } -} - -function backButtonShowHide(){ - "use strict"; - - $j(window).scroll(function () { - var b = $j(this).scrollTop(); - var c = $j(this).height(); - var d; - if (b > 0) { d = b + c / 2; } else { d = 1; } - if (d < 1e3) { totop_button("off"); } else { totop_button("on"); } - }); -} - -function backToTop(){ - "use strict"; - - $j(document).on('click','#back_to_top',function(e){ - e.preventDefault(); - - $j('body,html').animate({scrollTop: 0}, $j(window).scrollTop()/3, 'linear'); - }); -} - -/* - ** Init steps - */ -function initSteps(){ - "use strict"; - if($j('.q_steps_holder').length){ - $j('.q_steps_holder').each(function(){ - $j(this).appear(function() { - $j(this).addClass('show'); - },{accX: 0, accY: -200}); - }); - } -} - -/* - ** Init message height - */ -function initMessageHeight(){ - "use strict"; - if($j('.q_message.with_icon').length){ - $j('.q_message.with_icon').each(function(){ - if($j(this).find('.message_text_holder').height() > $j(this).find('.q_message_icon_holder').height()) { - $j(this).find('.q_message_icon_holder').height($j(this).find('.message_text').height()); - } else { - $j(this).find('.message_text').height($j(this).find('.q_message_icon_holder').height()); - } - }); - } -} - -/** - * Init image hover - */ -function initImageHover() { - "use strict"; - if($j('.image_hover').length){ - $j('.image_hover').each(function(){ - $j(this).appear(function() { - - var default_visible_time = 300; - var transition_delay = $j(this).attr('data-transition-delay'); - var real_transition_delay = default_visible_time + parseFloat(transition_delay); - var object = $j(this); - - //wait for other hovers to complete - setTimeout(function() { - object.addClass('show'); - }, parseFloat(transition_delay)); - - //hold that image a little, than remove class - setTimeout(function() { - object.removeClass('show'); - }, real_transition_delay); - - },{accX: 0, accY: -200}); - }); - } -} - -/* - * Initializes vertical progress bars - */ -function initProgressBarsVertical(){ - "use strict"; - - if($j('.q_progress_bars_vertical').length){ - $j('.q_progress_bars_vertical').each(function() { - $j(this).appear(function() { - initToCounterVerticalProgressBar($j(this)); - var percentage = $j(this).find('.progress_content').data('percentage'); - $j(this).find('.progress_content').css('height', '0%'); - $j(this).find('.progress_content').animate({ - height: percentage+'%' - }, 1500); - },{accX: 0, accY: -200}); - }); - } -} - -/* - * Initializes vertical progress bar count to max value - */ -function initToCounterVerticalProgressBar($this){ - "use strict"; - - if($this.find('.progress_number span').length){ - $this.find('.progress_number span').each(function() { - var $max = parseFloat($j(this).text()); - $j(this).countTo({ - from: 0, - to: $max, - speed: 1500, - refreshInterval: 50 - }); - }); - } -} - -/* -* Check if there is anchor on load and scroll to it -*/ -function checkAnchorOnLoad(){ - "use strict"; - - var hash = window.location.hash; - var paspartuScrollAdd = $j('body').hasClass('paspartu_on_top_fixed') ? $window_width*paspartu_width : 0; - var scrollToAmount; - var top_header_height; - if(hash !== "" && $j('[data-q_id="'+hash+'"]').length > 0){ - if($j('header.page_header').hasClass('fixed') && !$j('body').hasClass('vertical_menu_enabled')){ - if($j('header.page_header').hasClass('scroll_top')){ - top_header_height = header_top_height; - }else{ - top_header_height = 0; - } - - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { - if(header_height - ($j('[data-q_id="' + hash + '"]').offset().top + top_header_height)/4 >= min_header_height_scroll){ - var diff_of_header_and_section = $j('[data-q_id="' + hash + '"]').offset().top - header_height - paspartuScrollAdd; - scrollToAmount = diff_of_header_and_section + (diff_of_header_and_section/4) + (diff_of_header_and_section/16) + (diff_of_header_and_section/64) + 1; //several times od dividing to minimize the error, because fixed header is shrinking while scroll, 1 is just to ensure - }else{ - if($j('header.page_header').hasClass('centered_logo')){ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - logo_height - 30 - paspartuScrollAdd; //30 is top/bottom margin of logo - } else { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - paspartuScrollAdd; - } - } - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - - } else if($j('header.page_header').hasClass('fixed_top_header') && !$j('body').hasClass('vertical_menu_enabled')){ - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')){ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_top_height - paspartuScrollAdd; - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - - } else if($j('header.page_header').hasClass('fixed_hiding') && !$j('body').hasClass('vertical_menu_enabled')){ - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { - if ($j('[data-q_id="' + hash + '"]').offset().top - (header_height + logo_height / 2 + 40) <= scroll_amount_for_fixed_hiding) { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_height - logo_height / 2 - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo - } else { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_fixed_hidden - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo - } - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - }else if($j('header.page_header').hasClass('stick') || $j('header.page_header').hasClass('stick_with_left_right_menu') && !$j('body').hasClass('vertical_menu_enabled')) { - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { - if (sticky_amount >= $j('[data-q_id="' + hash + '"]').offset().top) { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top + 1 - paspartuScrollAdd; // 1 is to show sticky menu - } else { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_sticky - paspartuScrollAdd; - } - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - } else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - $j('html, body').animate({ - scrollTop: Math.round(scrollToAmount) - }, 1500, function() {}); - } - - //remove active state on anchors if section is not visible - $j(".main_menu a, .vertical_menu a, .mobile_menu a").each(function(){ - var i = $j(this).prop("hash"); - if(i !== "" && ($j('[data-q_id="' + i + '"]').length > 0) && ($j('[data-q_id="' + i + '"]').offset().top >= $window_height) && $scroll === 0){ - $j(this).parent().removeClass('active'); - $j(this).removeClass('current'); - } - }); -} - -/* -* Check active state of anchor links on scroll -*/ - -function changeActiveState(id){ - "use strict"; - - $j('.main_menu a').parent().removeClass('active'); - - $j(".main_menu a").each(function(){ - var i = $j(this).prop("hash"); - if(i === id){ - if($j(this).closest('.second').length === 0){ - $j(this).parent().addClass('active'); - }else{ - $j(this).closest('.second').parent().addClass('active'); - } - $j('.main_menu a').removeClass('current'); - $j(this).addClass('current'); - } - }); - - $j('.vertical_menu a').parent().removeClass('active'); - - $j(".vertical_menu a").each(function(){ - var i = $j(this).prop("hash"); - if(i === id){ - if($j(this).closest('.second').length === 0){ - $j(this).parent().addClass('active'); - }else{ - $j(this).closest('.second').parent().addClass('active'); - } - $j('.vertical_menu a').removeClass('current'); - $j(this).addClass('current'); - } - }); - - $j('.mobile_menu a').parent().removeClass('active'); - - $j(".mobile_menu a").each(function(){ - var i = $j(this).prop("hash"); - if(i === id){ - if($j(this).closest('.sub_menu').length === 0){ - $j(this).parent().addClass('active'); - }else{ - $j(this).closest('.sub_menu').parent().addClass('active'); - } - $j('.mobile_menu a').removeClass('current'); - $j(this).addClass('current'); - } - }); -} - -/* -* Check active state of anchor links on scroll -*/ -function checkAnchorOnScroll(){ - "use strict"; - - if($j('[data-q_id]').length && !$j('header.page_header').hasClass('regular')){ - $j('[data-q_id]').waypoint( function(direction) { - if(direction === 'down') { - changeActiveState($j(this).data("q_id")); - } - }, { offset: '50%' }); - - $j('[data-q_id]').waypoint( function(direction) { - if(direction === 'up') { - changeActiveState($j(this).data("q_id")); - } - }, { offset: function(){ - return -($j(this).outerHeight() - 150); - } }); - } -} - -/* -* Init scroll to section link if that link has hash value -*/ -function initHashClick(){ - "use strict"; - - var $doc = $j('html, body'); - var paspartuScrollAdd = $j('body').hasClass('paspartu_on_top_fixed') ? $window_width*paspartu_width : 0; - var scrollToAmount; - $j(document).on( "click", ".main_menu a, .vertical_menu a, .qbutton:not(.contact_form_button), .anchor, .widget li.anchor a", function(){ - var $this = $j(this); - var hash = $j(this).prop("hash"); - var top_header_height; - if((hash !== "" && $j(this).attr('href').split('#')[0] === "") || (hash !== "" && $j(this).attr('href').split('#')[0] !== "" && hash === window.location.hash) || (hash !== "" && $j(this).attr('href').split('#')[0] === window.location.href.split('#')[0])){ //in third condition 'hash !== ""' stays to prevent reload of page when link is active and ajax enabled - if($j('header.page_header').hasClass('fixed') && !$j('body').hasClass('vertical_menu_enabled')){ - if($j('header.page_header').hasClass('scroll_top')){ - top_header_height = header_top_height; - }else{ - top_header_height = 0; - } - - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { - if (header_height - ($j('[data-q_id="' + hash + '"]').offset().top + top_header_height) / 4 >= min_header_height_scroll) { - var diff_of_header_and_section = $j('[data-q_id="' + hash + '"]').offset().top - header_height - paspartuScrollAdd; - scrollToAmount = diff_of_header_and_section + (diff_of_header_and_section / 4) + (diff_of_header_and_section / 16) + (diff_of_header_and_section / 64) + 1; //several times od dividing to minimize the error, because fixed header is shrinking while scroll, 1 is just to ensure - } else { - if($j('header.page_header').hasClass('centered_logo')){ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - logo_height - paspartuScrollAdd - 30; //30 is top/bottom margin of logo - } else { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - paspartuScrollAdd; - } - } - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - - } - } else if($j('header.page_header').hasClass('fixed_top_header') && !$j('body').hasClass('vertical_menu_enabled')){ - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')){ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_top_height - paspartuScrollAdd; - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - } else if($j('header.page_header').hasClass('fixed_hiding') && !$j('body').hasClass('vertical_menu_enabled')){ - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { - if ($j('[data-q_id="' + hash + '"]').offset().top - (header_height + logo_height / 2 + 40) <= scroll_amount_for_fixed_hiding) { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_height - logo_height / 2 - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo - } else { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_fixed_hidden - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo - } - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - }else if($j('header.page_header').hasClass('stick') || $j('header.page_header').hasClass('stick_with_left_right_menu') && !$j('body').hasClass('vertical_menu_enabled')) { - if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { - if (sticky_amount >= $j('[data-q_id="' + hash + '"]').offset().top) { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top + 1 - paspartuScrollAdd; // 1 is to show sticky menu - } else { - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_sticky - paspartuScrollAdd; - } - }else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - } else{ - scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; - } - - - if($j('[data-q_id="'+hash+'"]').length > 0){ - $doc.stop().animate({ - scrollTop: Math.round(scrollToAmount) - }, 1500, function() { - anchorActiveState($this); - }); - - } - - if(history.pushState) { - history.pushState(null, null, hash); - } - return false; - } - - }); - $j(document).on( "click", ".mobile_menu a", function(){ - var $this = $j(this); - var hash = $j(this).prop("hash"); - if((hash !== "" && $j(this).attr('href').split('#')[0] === "") || (hash !== "" && $j(this).attr('href').split('#')[0] !== "" && hash === window.location.hash) || (hash !== "" && $j(this).attr('href').split('#')[0] === window.location.href.split('#')[0])){ //in third condition 'hash !== ""' stays to prevent reload of page when link is active and ajax enabled - - if($j('[data-q_id="'+hash+'"]').length > 0){ - $doc.animate({ - scrollTop: Math.round($j('[data-q_id="'+hash+'"]').offset().top - $j('.mobile_menu').height()) - }, 500,function(){ - anchorActiveState($this); - }); - - } - if(history.pushState) { - history.pushState(null, null, hash); - } - return false; - } - - }); -} - -/* -** Add class to items in last row in clients shortcode -*/ -function countClientsPerRow(){ - "use strict"; - - if($j('.qode_clients').length){ - - $j('.qode_clients').each(function() { - var $clients = $j(this); - var qode_clients_height = $clients.height(); - var qode_clients_width = $clients.width(); - var maxHeightClient; - var clientWidth = $clients.find('.qode_client_holder').width(); - var countClient = $clients.find('.qode_client_holder').length; - $clients.find('.qode_client_holder').each(function() { - maxHeightClient = maxHeightClient > $j(this).height() ? maxHeightClient : $j(this).height(); - }); - maxHeightClient = maxHeightClient + 35; //margin for client is 35 - var numberOfRows = Math.ceil(qode_clients_height / maxHeightClient); - var numberOfClientsPerRow = Math.ceil(qode_clients_width/clientWidth); - var numberOffullRows = Math.floor(countClient / numberOfClientsPerRow); - var numberOfClientsInLastRow = countClient - (numberOfClientsPerRow * numberOffullRows); - if(numberOfClientsInLastRow === 0){ - numberOfClientsInLastRow = numberOfClientsPerRow; - } - $clients.find( ".qode_client_holder" ).removeClass('border-bottom-none'); - var item_start_from = countClient - numberOfClientsInLastRow - 1; - $clients.find( ".qode_client_holder:gt("+ item_start_from +")" ).addClass('border-bottom-none'); - }); - } -} - -/* -** Calculate height for animated text icon shortcode -*/ -function animatedTextIconHeight(){ - "use strict"; - - if($j('.animated_icons_with_text').length){ - var $icons = $j('.animated_icons_with_text'); - var maxHeight; - - $icons.find('.animated_text p').each(function() { - maxHeight = maxHeight > $j(this).height() ? maxHeight : $j(this).height(); - }); - - if(maxHeight < 155) { - maxHeight = 155; - - } - $icons.find('.animated_icon_with_text_inner').height(maxHeight); - } -} - -/* -** Add class to items in last row in animated text icon shortcode -*/ -function countAnimatedTextIconPerRow(){ - "use strict"; - - if($j('.animated_icons_with_text').length){ - $j('.animated_icons_with_text').each(function() { - var $icons = $j(this); - var qode_icons_height = $icons.height(); - var qode_icons_width = $icons.width(); - var maxHeightIcons; - var iconWidth = $icons.find('.animated_icon_with_text_holder').width() + 1; // 1px because safari round on smaller number - var countIcons = $icons.find('.animated_icon_with_text_holder').length; - $icons.find('.animated_icon_with_text_holder').each(function() { - maxHeightIcons = maxHeightIcons > $j(this).height() ? maxHeightIcons : $j(this).height(); - }); - maxHeightIcons = maxHeightIcons + 30; //margin for client is 30 - var numberOfIconsPerRow = Math.ceil((qode_icons_width/iconWidth)); - var numberOffullRows = Math.floor(countIcons / numberOfIconsPerRow); - var numberOfIconsInLastRow = countIcons - (numberOfIconsPerRow * numberOffullRows); - if(numberOfIconsInLastRow === 0){ - numberOfIconsInLastRow = numberOfIconsPerRow; - } - $icons.find( ".animated_icon_with_text_holder" ).removeClass('border-bottom-none'); - var item_start_from = countIcons - numberOfIconsInLastRow - 1; - $icons.find( ".animated_icon_with_text_holder:gt("+ item_start_from +")" ).addClass('border-bottom-none'); - }); - } -} - - -/* -* Set active state in maim menu on anchor click -*/ - -function anchorActiveState(me){ - if(me.closest('.main_menu').length > 0){ - $j('.main_menu a').parent().removeClass('active'); - } - - if(me.closest('.vertical_menu').length > 0){ - $j('.vertical_menu a').parent().removeClass('active'); - } - - if(me.closest('.second').length === 0){ - me.parent().addClass('active'); - }else{ - me.closest('.second').parent().addClass('active'); - } - if(me.closest('.mobile_menu').length > 0){ - $j('.mobile_menu a').parent().removeClass('active'); - me.parent().addClass('active'); - } - - $j('.mobile_menu a, .main_menu a, .vertical_menu a').removeClass('current'); - me.addClass('current'); -} - -/* -** Video background initialization -*/ -function initVideoBackground(){ - "use strict"; - - $j('.video-wrap .video').mediaelementplayer({ - enableKeyboard: false, - iPadUseNativeControls: false, - pauseOtherPlayers: false, - // force iPhone's native controls - iPhoneUseNativeControls: false, - // force Android's native controls - AndroidUseNativeControls: false - }); - - //mobile check - if(navigator.userAgent.match(/(Android|iPod|iPhone|iPad|IEMobile|Opera Mini)/)){ - initVideoBackgroundSize(); - $j('.mobile-video-image').show(); - $j('.video-wrap').remove(); - } -} - -/* -** Calculate video background size -*/ -function initVideoBackgroundSize(){ - "use strict"; - - $j('.section .video-wrap').each(function(i){ - - var $sectionWidth = $j(this).closest('.section').outerWidth(); - $j(this).width($sectionWidth); - - var $sectionHeight = $j(this).closest('.section').outerHeight(); - min_w = vid_ratio * ($sectionHeight+20); - $j(this).height($sectionHeight); - - var scale_h = $sectionWidth / video_width_original; - var scale_v = ($sectionHeight - header_height) / video_height_original; - var scale = scale_v; - if (scale_h > scale_v) - scale = scale_h; - if (scale * video_width_original < min_w) {scale = min_w / video_width_original;} - - $j(this).find('video, .mejs-overlay, .mejs-poster').width(Math.ceil(scale * video_width_original +2)); - $j(this).find('video, .mejs-overlay, .mejs-poster').height(Math.ceil(scale * video_height_original +2)); - $j(this).scrollLeft(($j(this).find('video').width() - $sectionWidth) / 2); - $j(this).find('.mejs-overlay, .mejs-poster').scrollTop(($j(this).find('video').height() - ($sectionHeight)) / 2); - $j(this).scrollTop(($j(this).find('video').height() - ($sectionHeight)) / 2); - }); - - $j('.carousel .item .video .video-wrap').each(function(i){ - - var $slideWidth = $j(window).width(); - $j(this).width($slideWidth); - - var mob_header = $j(window).width() < 1000 ? $j('header.page_header').height() - 6 : 0; // 6 is because of the display: inline-block - var $slideHeight = $j(this).closest('.carousel.slide').height() - mob_header; - - min_w = vid_ratio * ($slideHeight+20); - $j(this).height($slideHeight); - - var scale_h = $slideWidth / video_width_original; - var scale_v = ($slideHeight - header_height) / video_height_original; - var scale = scale_v; - if (scale_h > scale_v) - scale = scale_h; - if (scale * video_width_original < min_w) {scale = min_w / video_width_original;} - - $j(this).find('video, .mejs-overlay, .mejs-poster').width(Math.ceil(scale * video_width_original +2)); - $j(this).find('video, .mejs-overlay, .mejs-poster').height(Math.ceil(scale * video_height_original +2)); - $j(this).scrollLeft(($j(this).find('video').width() - $slideWidth) / 2); - $j(this).find('.mejs-overlay, .mejs-poster').scrollTop(($j(this).find('video').height() - ($slideHeight)) / 2); - $j(this).scrollTop(($j(this).find('video').height() - ($slideHeight)) / 2); - }); - - $j('.portfolio_single .video .video-wrap, .blog_holder .video .video-wrap').each(function(i){ - - var $this = $j(this); - - var $videoWidth = $j(this).closest('.video').outerWidth(); - $j(this).width($videoWidth); - var $videoHeight = ($videoWidth*9)/16; - - if(navigator.userAgent.match(/(Android|iPod|iPhone|iPad|IEMobile|Opera Mini)/)){ - $this.parent().width($videoWidth); - $this.parent().height($videoHeight); - } - - min_w = vid_ratio * ($videoHeight+20); - $j(this).height($videoHeight); - - var scale_h = $videoWidth / video_width_original; - var scale_v = ($videoHeight - header_height) / video_height_original; - var scale = scale_v; - if (scale_h > scale_v) - scale = scale_h; - if (scale * video_width_original < min_w) {scale = min_w / video_width_original;} - - $j(this).find('video, .mejs-overlay, .mejs-poster').width(Math.ceil(scale * video_width_original +2)); - $j(this).find('video, .mejs-overlay, .mejs-poster').height(Math.ceil(scale * video_height_original +2)); - $j(this).scrollLeft(($j(this).find('video').width() - $videoWidth) / 2); - $j(this).find('.mejs-overlay, .mejs-poster').scrollTop(($j(this).find('video').height() - ($videoHeight)) / 2); - $j(this).scrollTop(($j(this).find('video').height() - ($videoHeight)) / 2); - }); - -} - -/* -** Icon With Text animation effect -*/ -function initIconWithTextAnimation(){ - "use strict"; - if($j('.q_icon_animation').length > 0 && $j('.no_animation_on_touch').length === 0){ - $j('.q_icon_animation').each(function(){ - $j(this).appear(function() { - $j(this).addClass('q_show_animation'); - },{accX: 0, accY: -200}); - }); - } -} - -/* -** Add class on body if browser is Safari -*/ -function initCheckSafariBrowser(){ - "use strict"; - - if (navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) { - $j('body').addClass('safari_browser'); - } -} - -/* -** Initialize Qode search form -*/ -function initSearchButton(){ - - if($j('.search_slides_from_window_top').length){ - $j('.search_slides_from_window_top').click(function(e){ - e.preventDefault(); - - if($j('html').hasClass('touch')){ - if ($j('.qode_search_form').height() == "0") { - $j('.qode_search_form input[type="text"]').onfocus = function () { - window.scrollTo(0, 0); - document.body.scrollTop = 0; - }; - $j('.qode_search_form input[type="text"]').onclick = function () { - window.scrollTo(0, 0); - document.body.scrollTop = 0; - }; - $j('.header_top_bottom_holder').css('top','50px'); - $j('.qode_search_form').css('height','50px'); - $j('.content_inner').css('margin-top','50px'); - if($scroll < 34){ $j('header.page_header').css('top','0'); } - } else { - $j('.qode_search_form').css('height','0'); - $j('.header_top_bottom_holder').css('top','0'); - $j('.content_inner').css('margin-top','0'); - if($scroll < 34){ $j('header.page_header').css('top',-$scroll);} - } - - $j(window).scroll(function() { - if ($j('.qode_search_form').height() != "0" && $scroll > 50) { - $j('.qode_search_form').css('height','0'); - $j('.header_top_bottom_holder').css('top','0'); - $j('.content_inner').css('margin-top','0'); - } - }); - - $j('.qode_search_close').click(function(e){ - e.preventDefault(); - $j('.qode_search_form').css('height','0'); - $j('.header_top_bottom_holder').css('top','0'); - $j('.content_inner').css('margin-top','0'); - if($scroll < 34){ $j('header.page_header').css('top',-$scroll);} - }); - - } else { - if($j('.title').hasClass('has_fixed_background')){ - var yPos = parseInt($j('.title.has_fixed_background').css('backgroundPosition').split(" ")[1]); - }else { - var yPos = 0; - } - if ($j('.qode_search_form').height() == "0") { - $j('.qode_search_form input[type="text"]').focus(); - $j('.header_top_bottom_holder').stop().animate({top:"50px"},150); - $j('.qode_search_form').stop().animate({height:"50px"},150); - $j('.content_inner').stop().animate({marginTop:"50px"},150); - if($scroll < 34){ $j('header.page_header').stop().animate({top:0},150); } - $j('.title.has_fixed_background').animate({ - 'background-position-y': (yPos + 50)+'px' - }, 150); - } else { - $j('.qode_search_form').stop().animate({height:"0"},150); - $j('.header_top_bottom_holder').stop().animate({top:"0px"},150); - $j('.content_inner').stop().animate({marginTop:"0"},150); - if($scroll < 34){ $j('header.page_header').stop().animate({top:-$scroll},150);} - $j('.title.has_fixed_background').animate({ - 'background-position-y': (yPos - 50)+'px' - }, 150); - } - - $j(window).scroll(function() { - if ($j('.qode_search_form').height() != "0" && $scroll > 50) { - $j('.qode_search_form').stop().animate({height:"0"},150); - $j('.header_top_bottom_holder').stop().animate({top:"0px"},150); - $j('.content_inner').stop().animate({marginTop:"0"},150); - $j('.title.has_fixed_background').css('backgroundPosition', 'center '+(yPos)+'px'); - } - }); - - $j('.qode_search_close').click(function(e){ - e.preventDefault(); - $j('.qode_search_form').stop().animate({height:"0"},150); - $j('.content_inner').stop().animate({marginTop:"0"},150); - $j('.header_top_bottom_holder').stop().animate({top:"0px"},150); - if($scroll < 34){ $j('header.page_header').stop().animate({top:-$scroll},150);} - $j('.title.has_fixed_background').animate({ - 'background-position-y': (yPos)+'px' - }, 150); - }); - } - }); - } - - //search type - search_slides_from_header_bottom - if($j('.search_slides_from_header_bottom').length){ - - $j('.search_slides_from_header_bottom').click(function(e){ - - e.preventDefault(); - - if($j('html').hasClass('touch')){ - if ($j('.qode_search_form_2').height() == "0") { - $j('.qode_search_form_2 input[type="text"]').onfocus = function () { - window.scrollTo(0, 0); - document.body.scrollTop = 0; - }; - $j('.qode_search_form_2 input[type="text"]').onclick = function () { - window.scrollTo(0, 0); - document.body.scrollTop = 0; - }; - $j('.qode_search_form_2').css('height','50px'); - } else { - $j('.qode_search_form_2').css('height','0'); - - } - - $j(window).scroll(function() { - if ($j('.qode_search_form_2').height() != "0" && $scroll > 50) { - $j('.qode_search_form_2').css('height','0'); - } - }); - - } else { - if($j('.qode_search_form_2').hasClass('animated')) { - $j('.qode_search_form_2').removeClass('animated'); - $j('.qode_search_form_2').css('bottom','0'); - } else { - $j('.qode_search_form input[type="text"]').focus(); - $j('.qode_search_form_2').addClass('animated'); - var search_form_height = $j('.qode_search_form_2').height(); - $j('.qode_search_form_2').css('bottom',-search_form_height); - - } - - $j('.qode_search_form_2').addClass('disabled'); - $j('.qode_search_form_2 input[type="submit"]').attr('disabled','disabled'); - if(($j('.qode_search_form_2 .qode_search_field').val() !== '') && ($j('.qode_search_form_2 .qode_search_field').val() !== ' ')) { - $j('.qode_search_form_2 input[type="submit"]').removeAttr('disabled'); - $j('.qode_search_form_2').removeClass('disabled'); - } - else { - $j('.qode_search_form_2').addClass('disabled'); - $j('.qode_search_form_2 input[type="submit"]').attr('disabled','disabled'); - } - - $j('.qode_search_form_2 .qode_search_field').keyup(function() { - if(($j(this).val() !== '') && ($j(this).val() != ' ')) { - $j('.qode_search_form_2 input[type="submit"]').removeAttr('disabled'); - $j('.qode_search_form_2').removeClass('disabled'); - } - else { - $j('.qode_search_form_2 input[type="submit"]').attr('disabled','disabled'); - $j('.qode_search_form_2').addClass('disabled'); - } - }); - - - $j('.content, footer').click(function(e){ - e.preventDefault(); - $j('.qode_search_form_2').removeClass('animated'); - $j('.qode_search_form_2').css('bottom','0'); - }); - } - }); - } - - //search type - search covers header - if($j('.search_covers_header').length){ - - $j('.search_covers_header').click(function(e){ - - e.preventDefault(); - if($j(".search_covers_only_bottom").length){ - var headerHeight = $j('.header_bottom').height(); - } - else{ - if($j(".fixed_top_header").length){ - var headerHeight = $j('.top_header').height(); - }else{ - var headerHeight = $j('.header_top_bottom_holder').height(); - } - } - - $j('.qode_search_form_3 .form_holder_outer').height(headerHeight); - - if($j(".search_covers_only_bottom").length){ - $j('.qode_search_form_3').css('bottom',0); - $j('.qode_search_form_3').css('top','auto'); - } - $j('.qode_search_form_3').stop(true).fadeIn(600,'easeOutExpo'); - $j('.qode_search_form_3 input[type="text"]').focus(); - - - $j(window).scroll(function() { - if($j(".search_covers_only_bottom").length){ - var headerHeight = $j('.header_bottom').height(); - } - else{ - if($j(".fixed_top_header").length){ - var headerHeight = $j('.top_header').height(); - }else{ - var headerHeight = $j('.header_top_bottom_holder').height(); - } - } - $j('.qode_search_form_3 .form_holder_outer').height(headerHeight); - }); - - $j('.qode_search_close, .content, footer').click(function(e){ - e.preventDefault(); - $j('.qode_search_form_3').stop(true).fadeOut(450,'easeOutExpo'); - }); - - $j('.qode_search_form_3').blur(function(e){ - $j('.qode_search_form_3').stop(true).fadeOut(450,'easeOutExpo'); - }); - }); - } - -//search type - fullscreen search - if($j('.fullscreen_search').length){ - //search type Circle Appear - if($j(".fullscreen_search_holder.from_circle").length){ - $j('.fullscreen_search').on('click',function(e){ - e.preventDefault(); - if($j('.fullscreen_search_overlay').hasClass('animate')){ - $j('.fullscreen_search_overlay').removeClass('animate'); - $j('.fullscreen_search_holder').css('opacity','0'); - $j('.fullscreen_search_close').css('opacity','0'); - $j('.fullscreen_search_close').css('visibility','hidden'); - $j('.fullscreen_search').css('opacity','1'); - $j('.fullscreen_search_holder').css('display','none'); - } else { - $j('.fullscreen_search_overlay').addClass('animate'); - $j('.fullscreen_search_holder').css('display','block'); - setTimeout(function(){ - $j('.fullscreen_search_holder').css('opacity','1'); - $j('.fullscreen_search_close').css('opacity','1'); - $j('.fullscreen_search_close').css('visibility','visible'); - $j('.fullscreen_search').css('opacity','0'); - },200); - - } - }); - $j('.fullscreen_search_close').on('click',function(e){ - e.preventDefault(); - $j('.fullscreen_search_overlay').removeClass('animate'); - $j('.fullscreen_search_holder').css('opacity','0'); - $j('.fullscreen_search_close').css('opacity','0'); - $j('.fullscreen_search_close').css('visibility','hidden'); - $j('.fullscreen_search').css('opacity','1'); - $j('.fullscreen_search_holder').css('display','none'); - - }); - } - //search type Fade Appear - if($j(".fullscreen_search_holder.fade").length){ - $j('.fullscreen_search').on('click',function(e){ - e.preventDefault(); - if($j('.fullscreen_search_holder').hasClass('animate')) { - $j('body').removeClass('fullscreen_search_opened'); - $j('.fullscreen_search_holder').removeClass('animate'); - $j('body').removeClass('search_fade_out'); - $j('body').removeClass('search_fade_in'); - - } else { - $j('body').addClass('fullscreen_search_opened'); - $j('body').removeClass('search_fade_out'); - $j('body').addClass('search_fade_in'); - $j('.fullscreen_search_holder').addClass('animate'); - - } - }); - $j('.fullscreen_search_close').on('click',function(e){ - e.preventDefault(); - $j('body').removeClass('fullscreen_search_opened'); - $j('.fullscreen_search_holder').removeClass('animate'); - $j('body').removeClass('search_fade_in'); - $j('body').addClass('search_fade_out'); - - }); - } - - //Text input focus change - $j('.fullscreen_search_holder .search_field').focus(function(){ - $j('.fullscreen_search_holder .field_holder .line').css("width","100%"); - }); - - $j('.fullscreen_search_holder .search_field').blur(function(){ - $j('.fullscreen_search_holder .field_holder .line').css("width","0"); - }); - - //search close button - setting its position vertically - $j(window).scroll(function() { - var bottom_height = $j(".page_header .header_bottom").height(); - if($j(".page_header").hasClass("sticky")){ - $j(".fullscreen_search_holder .side_menu_button").css("height",bottom_height); - $j(".fullscreen_search_holder .close_container").css("top","0"); - } else if($j(".page_header").hasClass("fixed")){ - $j(".fullscreen_search_holder .side_menu_button").css("height",bottom_height); - } else { - $j(".fullscreen_search_holder .side_menu_button").css("height",""); - $j(".fullscreen_search_holder .close_container").css("top",""); - } - }); - } - - if($j('.qode_search_submit').length) { - $j('.qode_search_submit').click(function(e) { - e.preventDefault(); - e.stopPropagation(); - - var searchForm = $j(this).parents('form').first(); - - searchForm.submit(); - }); - } - -} - -/* -** Init update Shopping Cart -*/ -function updateShoppingCart(){ - "use strict"; - - $j('body').bind('added_to_cart', add_to_cart); - function add_to_cart(event, parts, hash) { - var miniCart = $j('.shopping_cart_header'); - if ( parts['div.widget_shopping_cart_content'] ) { - var $cartContent = jQuery(parts['div.widget_shopping_cart_content']), - $itemsList = $cartContent .find('.cart_list'), - $total = $cartContent.find('.total').contents(':not(strong)').text(); - miniCart.find('.shopping_cart_dropdown_inner').html('').append($itemsList); - miniCart.find('.total span').html('').append($total); - } - } -} - - -/* -** Set content bottom margin because of the uncovering footer -*/ -function setContentBottomMargin(){ - if($j('.uncover').length){ - $j('.content').css('margin-bottom', $j('footer').height()); - } -} - -/* - ** Set footer uncover with vertical area - */ -function footerWidth(){ - "use strict"; - - if($j('.uncover').length && $j('body').hasClass('vertical_menu_enabled') && $window_width > 1000){ - $j('.uncover').width($window_width - $j('.vertical_menu_area').width()); - } else{ - $j('.uncover').css('width','100%'); - } -} - -/* -** Boxes which reveal text on hover -*/ -function initCoverBoxes(){ - if($j('.cover_boxes').length) { - $j('.cover_boxes').each(function(){ - var active_element = 0; - var data_active_element = 1; - if(typeof $j(this).data('active-element') !== 'undefined' && $j(this).data('active-element') !== false) { - data_active_element = parseFloat($j(this).data('active-element')); - active_element = data_active_element - 1; - } - - var number_of_columns = 3; - - //validate active element - active_element = data_active_element > number_of_columns ? 0 : active_element; - - $j(this).find('li').eq(active_element).addClass('act'); - var cover_boxed = $j(this); - $j(this).find('li').each(function(){ - $j(this).hover(function() { - $j(cover_boxed).find('li').removeClass('act'); - $j(this).addClass('act'); - }); - - }); - }); - } -} - -/* -** Create content menu from selected rows -*/ -function createContentMenu(){ - "use strict"; - - var content_menu = $j(".content_menu"); - content_menu.each(function(){ - if($j(this).find('ul').length === 0){ - - if($j(this).css('background-color') !== ""){ - var background_color = $j(this).css('background-color'); - } - - var content_menu_ul = $j(""); - content_menu_ul.appendTo($j(this)); - - var sections = $j(this).siblings('.in_content_menu'); - - if(sections.length){ - sections.each(function(){ - var section_href = $j(this).data("q_id"); - var section_title = $j(this).data('q_title'); - var section_icon = $j(this).data('q_icon'); - - var li = $j("
  • "); - var icon = $j("", {"class": 'fa '+section_icon}); - var link = $j("", {"href": section_href, "html": "" + section_title + ""}); - var arrow; - if(background_color !== ""){ - arrow = $j("
    ", {"class": 'arrow', "style": 'border-color: '+background_color+' transparent transparent transparent'}); - } else { - arrow = $j("
    ", {"class": 'arrow'}); - } - icon.prependTo(link); - link.appendTo(li); - arrow.appendTo(li); - li.appendTo(content_menu_ul); - - }); - } - } - }); -} - -/* -** Create content menu (select menu for responsiveness)from selected rows -*/ -function createSelectContentMenu(){ - "use strict"; - - var content_menu = $j(".content_menu"); - content_menu.each(function(){ - - var $this = $j(this); - - var $menu_select = $j("
      "); - $menu_select.appendTo($j(this).find('.nav_select_menu')); - - - $j(this).find("ul.menu li a").each(function(){ - - var menu_url = $j(this).attr("href"); - var menu_text = $j(this).text(); - var menu_icon = $j(this).find('i').clone(); - - if ($j(this).parents("li").length === 2) { menu_text = "   " + menu_text; } - if ($j(this).parents("li").length === 3) { menu_text = "      " + menu_text; } - if ($j(this).parents("li").length > 3) { menu_text = "         " + menu_text; } - - var li = $j("
    • "); - var link = $j("", {"href": menu_url, "html": menu_text}); - menu_icon.prependTo(link); - link.appendTo(li); - li.appendTo($menu_select); - }); - - - $this.find(".nav_select_button").on('click', function() { - if ($this.find('.nav_select_menu ul').is(":visible")){ - $this.find('.nav_select_menu ul').slideUp(); - } else { - $this.find('.nav_select_menu ul').slideDown(); - } - return false; - }); - - $this.find(".nav_select_menu ul li a").on('click',function () { - $this.find('.nav_select_menu ul').slideUp(); - var $link = $j(this); - - var $target = $link.attr("href"); - var targetOffset = $j("div.wpb_row[data-q_id='" + $target + "'],section.parallax_section_holder[data-q_id='" + $target + "']").offset().top; - - $j('html,body').stop().animate({scrollTop: targetOffset }, 500, 'swing', function(){ - $j('nav.content_menu ul li').removeClass('active'); - $link.parent().addClass('active'); - }); - - return false; - }); - }); -} - -/* -** Calculate content menu position and fix it when needed -*/ -function contentMenuPosition(){ - "use strict"; - - if($j('nav.content_menu').length){ - - if(content_menu_position > sticky_amount){ - var x = min_header_height_sticky; - }else{ - var x = 0; - } - - if(content_menu_position - x - content_menu_top_add - $scroll <= 0 && ($j('header').hasClass('stick') || $j('header').hasClass('stick_with_left_right_menu'))){ - - if(content_menu_position < sticky_amount){ - if($scroll > sticky_amount){ - $j('nav.content_menu').css({'position': 'fixed', 'top': min_header_height_sticky + content_menu_top_add}).addClass('fixed'); - - }else{ - $j('nav.content_menu').css({'position': 'fixed', 'top': 0, transition:'none'}).addClass('fixed'); - } - }else{ - $j('nav.content_menu').css({'position': 'fixed', 'top': min_header_height_sticky + content_menu_top_add}).addClass('fixed'); - } - $j('header.sticky').addClass('no_shadow'); - $j('.content > .content_inner > .container > .container_inner').css('margin-top',content_line_height); - $j('.content > .content_inner > .full_width').css('margin-top',content_line_height); - - } else if(content_menu_position - content_menu_top - content_menu_top_add - $scroll <= 0 && !($j('header').hasClass('stick'))) { - $j('nav.content_menu').css({'position': 'fixed', 'top': content_menu_top + content_menu_top_add}).addClass('fixed'); - $j('.content > .content_inner > .container > .container_inner').css('margin-top',content_line_height); - $j('.content > .content_inner > .full_width').css('margin-top',content_line_height); - } else { - $j('nav.content_menu').css({'position': 'relative', 'top': '0px'}).removeClass('fixed'); - $j('header.sticky').removeClass('no_shadow'); - $j('.content > .content_inner > .container > .container_inner').css('margin-top','0px'); - $j('.content > .content_inner > .full_width').css('margin-top','0px'); - } - - $j('.content .in_content_menu').waypoint( function(direction) { - var $active = $j(this); - var id = $active.data("q_id"); - - $j("nav.content_menu.fixed li a").each(function(){ - var i = $j(this).attr("href"); - if(i === id){ - $j(this).parent().addClass('active'); - }else{ - $j(this).parent().removeClass('active'); - } - }); - }, { offset: '150' }); - } -} - -/* -** Check first and last content menu included rows for active state in content menu -*/ -function contentMenuCheckLastSection(){ - "use strict"; - - if($j('nav.content_menu').length){ - - if($j('.content .in_content_menu').length){ - var last_from_top = $j('.content .in_content_menu:last').offset().top + $j('.content .in_content_menu:last').height(); - var first_from_top = $j('.content .in_content_menu:first').offset().top - content_menu_top - content_menu_top_add - 100; //60 is height of content menu - if(last_from_top < $scroll){ - $j("nav.content_menu.fixed li").removeClass('active'); - - } - if(first_from_top > $scroll){ - $j('nav.content_menu li:first, nav.content_menu ul.menu li:first').removeClass('active'); - - } - } - - } -} - -/* -** Scroll to section when item in content menu is clicked -*/ -function contentMenuScrollTo(){ - "use strict"; - - if($j('nav.content_menu').length){ - - $j("nav.content_menu ul.menu li a").on('click', function(e){ - e.preventDefault(); - var $this = $j(this); - - if($j(this).parent().hasClass('active')){ - return false; - } - - var $target = $this.attr("href"); - var targetOffset = $j("div.wpb_row[data-q_id='" + $target + "'],section.parallax_section_holder[data-q_id='" + $target + "']").offset().top - content_line_height - content_menu_top - content_menu_top_add; - $j('html,body').stop().animate({scrollTop: targetOffset }, 500, 'swing', function(){ - $j('nav.content_menu ul li').removeClass('active'); - $this.parent().addClass('active'); - }); - - return false; - }); - - } -} - -function initButtonHover() { - if($j('.qbutton').length) { - $j('.qbutton').each(function() { - - //hover background color - if(typeof $j(this).data('hover-background-color') !== 'undefined' && $j(this).data('hover-background-color') !== false) { - var hover_background_color = $j(this).data('hover-background-color'); - var initial_background_color = $j(this).css('background-color'); - $j(this).hover( - function() { - $j(this).css('background-color', hover_background_color); - }, - function() { - $j(this).css('background-color', initial_background_color); - }); - } - - //hover border color - if(typeof $j(this).data('hover-border-color') !== 'undefined' && $j(this).data('hover-border-color') !== false) { - var hover_border_color = $j(this).data('hover-border-color'); - var initial_border_color = $j(this).css('border-top-color'); - $j(this).hover( - function() { - $j(this).css('border-color', hover_border_color); - }, - function() { - $j(this).css('border-color', initial_border_color); - }); - } - - //hover color - if(typeof $j(this).data('hover-color') !== 'undefined' && $j(this).data('hover-color') !== false) { - var hover_color = $j(this).data('hover-color'); - var initial_color = $j(this).css('color'); - $j(this).hover( - function() { - $j(this).css('color', hover_color); - }, - function() { - $j(this).css('color', initial_color); - }); - } - }); - } -} - -function initSocialIconHover() { - if($j('.q_social_icon_holder').length) { - $j('.q_social_icon_holder').each(function() { - - //hover background color - if(typeof $j(this).data('hover-background-color') !== 'undefined' && $j(this).data('hover-background-color') !== false) { - var hover_background_color = $j(this).data('hover-background-color'); - var initial_background_color = $j(this).find('.fa-stack').css('background-color'); - $j(this).find('.fa-stack').hover( - function() { - - $j(this).css('background-color', hover_background_color); - }, - function() { - $j(this).css('background-color', initial_background_color); - }); - } - - //hover border color - if(typeof $j(this).data('hover-border-color') !== 'undefined' && $j(this).data('hover-border-color') !== false) { - var hover_border_color = $j(this).data('hover-border-color'); - var initial_border_color = $j(this).find('.fa-stack').css('border-top-color'); - $j(this).find('.fa-stack').hover( - function() { - $j(this).css('border-color', hover_border_color); - }, - function() { - $j(this).css('border-color', initial_border_color); - } - ); - } - - //hover color - if(typeof $j(this).data('hover-color') !== 'undefined' && $j(this).data('hover-color') !== false) { - var initial_color; - var initial_style; - var hover_color = $j(this).data('hover-color'); - - if($j(this).find('.fa-stack i, .fa-stack span').length) { - initial_color = $j(this).find('.fa-stack i, .fa-stack span').css('color'); - initial_style = $j(this).find('.fa-stack i, .fa-stack span').attr('style'); - } else if($j(this).find('.simple_social').length) { - initial_color = $j(this).find('.simple_social').css('color'); - initial_style = $j(this).find('.simple_social').attr('style'); - } - - if($j(this).find('.fa-stack').length) { - $j(this).find('.fa-stack').hover( - function() { - $j(this).find('i, span').attr('style', function(i, s) { return initial_style + 'color: '+ hover_color + '!important;'}); - }, - function() { - $j(this).find('i, span').attr('style', function(i, s) { return initial_style + 'color: ' + initial_color + '!important;' }); - }); - } else if($j(this).find('.simple_social').length) { - $j(this).find('.simple_social').hover( - function(){ - $j(this).attr('style', function(i, s) { return initial_style + 'color: '+ hover_color + '!important;' }); - }, - function(){ - $j(this).attr('style', function(i, s) { return initial_style + 'color: '+ initial_color + '!important;' }); - }); - } - - } - }); - } -} - -function initTabsActiveBorder() { - if($j('.q_tabs.vertical, .q_tabs.boxed').length) { - $j('.q_tabs.vertical, .q_tabs.boxed').each(function(){ - var parentBgColor = getParentBackgroundColor($j(this)); - - var activeElement = $j(this).find('li.active a'); - if($j(this).hasClass('boxed')) { - activeElement.css('border-bottom-color', parentBgColor); - } - - if($j(this).hasClass('left')) { - activeElement.css('border-right-color', parentBgColor); - } - - if($j(this).hasClass('right')) { - activeElement.css('border-left-color', parentBgColor); - } - }); - } -} - -function getParentBackgroundColor(element) { - return element.parents().filter(function(){ - var color = $j(this).css('background-color'); - return color != 'transparent' && color != 'rgba(0, 0, 0, 0)'; - }).eq(0).css('background-color') -} - -function setActiveTabBorder() { - if($j('.q_tabs li.active').length) { - $j(this).click(function() { - initTabsActiveBorder(); - }); - } -} - -/* - ** Popup menu initialization - */ - -function initPopupMenu(){ - "use strict"; - - if($j('a.popup_menu').length){ - //var body_top; - - //set height of popup holder and initialize nicescroll - $j(".popup_menu_holder_outer").height($window_height).niceScroll({ - scrollspeed: 30, - mousescrollstep: 20, - cursorwidth: 0, - cursorborder: 0, - cursorborderradius: 0, - cursorcolor: "transparent", - autohidemode: false, - horizrailenabled: false - }); //200 is top and bottom padding of holder - - //set height of popup holder on resize - $j(window).resize(function() {$j(".popup_menu_holder_outer").height($window_height)}); - - // Open popup menu - $j('a.popup_menu').on('click',function(e){ - e.preventDefault(); - - if(!$j(this).hasClass('opened')){ - $j(this).addClass('opened'); - $j('body').addClass('popup_menu_opened'); - setTimeout(function(){ - if(!$j('body').hasClass('page-template-full_screen-php')){ - $j('body').css('overflow','hidden'); - } - },400); - }else{ - $j(this).removeClass('opened'); - $j('body').removeClass('popup_menu_opened'); - - setTimeout(function(){ - if(!$j('body').hasClass('page-template-full_screen-php')){ - $j('body').css('overflow','visible'); - } - $j("nav.popup_menu ul.sub_menu").slideUp(200, function(){ - $j('nav.popup_menu').getNiceScroll().resize(); - }); - },400); - - } - }); - - //logic for open sub menus in popup menu - $j(".popup_menu > ul > li.has_sub > a, .popup_menu > ul > li.has_sub > h6").on('tap click', function (e) { - e.preventDefault(); - - if ($j(this).closest('li.has_sub').find("> ul.sub_menu").is(":visible")){ - $j(this).closest('li.has_sub').find("> ul.sub_menu").slideUp(200, function(){ - $j('.popup_menu_holder_outer').getNiceScroll().resize(); - }); - $j(this).closest('li.has_sub').removeClass('open_sub'); - } else { - $j(this).closest('li.has_sub').addClass('open_sub'); - $j(this).closest('li.has_sub').find("> ul.sub_menu").slideDown(200, function(){ - $j('.popup_menu_holder_outer').getNiceScroll().resize(); - }); - } - - return false; - }); - -// $j(".popup_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > a > span.popup_arrow, .popup_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > h6").click(function () { -// if ($j(this).parent().parent().find("ul.sub_menu").is(":visible")){ -// $j(this).parent().parent().find("ul.sub_menu").slideUp(200); -// $j(this).parent().parent().removeClass('open_sub'); -// } else { -// $j(this).parent().parent().addClass('open_sub'); -// $j(this).parent().parent().find("ul.sub_menu").slideDown(200); -// } -// }); - - //if link has no submenu and if it's not dead, than open that link - $j(".popup_menu ul li:not(.has_sub) a").click(function () { - if(($j(this).attr('href') !== "http://#") && ($j(this).attr('href') !== "#")){ - $j('a.popup_menu').removeClass('opened'); - $j('body').removeClass('popup_menu_opened').css('overflow','visible'); - $j("nav.popup_menu ul.sub_menu").slideUp(200, function(){ - $j('nav.popup_menu').getNiceScroll().resize(); - }); - }else{ - return false; - } - }); - } -} - -function initFullScreenTemplate(){ - "use strict"; - - if($j('.full_screen_holder').length && $window_width > 600){ - - // used for header style on changing sections, in checkFullScreenSectionsForHeaderStyle functions - START // - var default_header_style = ''; - if ($j('header.page_header').hasClass('light')) { - default_header_style = 'light'; - } else if ($j('header.page_header').hasClass('dark')) { - default_header_style = 'dark'; - } else { - default_header_style = header_style_admin; - } - // used for header style on changing sections, in checkFullScreenSectionsForHeaderStyle functions - END // - - $j('.full_screen_preloader').css('height', ($window_height)); - - $j('#up_fs_button').on('click', function() { - $j.fn.fullpage.moveSectionUp(); - return false; - }); - - $j('#down_fs_button').on('click', function() { - $j.fn.fullpage.moveSectionDown(); - return false; - }); - - var section_number = $j('.full_screen_inner > .full_screen_section').length; - $j('.full_screen_inner').fullpage({ - sectionSelector: '.full_screen_section', - scrollOverflow: true, - afterLoad: function(anchorLink, index){ - checkActiveArrowsOnFullScrrenTemplate(section_number, index); - checkFullScreenSectionsForHeaderStyle(index, default_header_style); - }, - afterRender: function(){ - checkActiveArrowsOnFullScrrenTemplate(section_number, 1); - checkFullScreenSectionsForHeaderStyle(1, default_header_style); - if(section_number !== 1){ - $j('.full_screen_holder').find('.full_screen_navigation_holder').css('visibility','visible'); - } - $j('.full_screen_holder').find('.full_screen_inner').css('visibility','visible'); - $j('.full_screen_preloader').hide(); - if($j('.full_screen_holder video.full_screen_sections_video').length){ - $j('.full_screen_holder video.full_screen_sections_video').each(function(){ - $j(this).get(0).play(); - }); - } - } - }); - } -} - -function checkActiveArrowsOnFullScrrenTemplate(section_number, index){ - "use strict"; - - if(index === 1){ - $j('.full_screen_navigation_holder #up_fs_button').hide(); - if(index != section_number){ - $j('.full_screen_navigation_holder #down_fs_button').show(); - } - }else if(index === section_number){ - if(section_number === 2){ - $j('.full_screen_navigation_holder #up_fs_button').show(); - } - $j('.full_screen_navigation_holder #down_fs_button').hide(); - }else{ - $j('.full_screen_navigation_holder #up_fs_button').show(); - $j('.full_screen_navigation_holder #down_fs_button').show(); - } -} - -function checkFullScreenSectionsForHeaderStyle(index, default_header_style){ - "use strict"; - - if($j('[data-q_header_style]').length > 0 && $j('header').hasClass('header_style_on_scroll')) { - if ($j($j('.full_screen_holder .full_screen_inner .full_screen_section')[index-1]).data("q_header_style") !== undefined) { - var header_style = $j($j('.full_screen_holder .full_screen_inner .full_screen_section')[index-1]).data("q_header_style"); - $j('header').removeClass('dark light').addClass(header_style); - } else { - - $j('header').removeClass('dark light').addClass(default_header_style); - } - } -} - -/* - * Check header style on scroll - */ - -function checkHeaderStyleOnScroll(){ - "use strict"; - - if($j('[data-q_header_style]').length > 0 && $j('header').hasClass('header_style_on_scroll')){ - - //var offset = $j('header.page_header').height(); - var default_header_style = ''; - if($j('header.page_header').hasClass('light')){ - default_header_style = 'light'; - }else if($j('header.page_header').hasClass('dark')){ - default_header_style = 'dark'; - }else{ - default_header_style = header_style_admin; - } - - var paspartu_top_add = $j('body').hasClass('paspartu_on_top_fixed') ? Math.round($window_width*paspartu_width) : 0; - var paspartu_bottom_add = $j('body').hasClass('paspartu_on_bottom_fixed') ? Math.round($window_width*paspartu_width) : 0; - - $j('.full_width_inner > .wpb_row.section, .full_width_inner > .parallax_section_holder, .container_inner > .wpb_row.section, .container_inner > .parallax_section_holder, .portfolio_single > .wpb_row.section').waypoint( function(direction) { - if(direction === 'down') { - if ($j(this).data("q_header_style") !== undefined) { - var header_style = $j(this).data("q_header_style"); - $j('header').removeClass('dark light').addClass(header_style); - } else { - $j('header').removeClass('dark light').addClass(default_header_style); - } - } - - }, { offset: 0 + paspartu_top_add}); - - //'title' class is added in selector because default header style is not set when there is title on the page and page is scrolled back to the top - $j('.title, .full_width_inner > .wpb_row.section, .full_width_inner > .parallax_section_holder, .container_inner > .wpb_row.section, .container_inner > .parallax_section_holder, .portfolio_single > .wpb_row.section, .q_slider').waypoint( function(direction) { - - if(direction === 'up') { - if ($j(this).data("q_header_style") !== undefined) { - var header_style = $j(this).data("q_header_style"); - $j('header').removeClass('dark light').addClass(header_style); - } else { - $j('header').removeClass('dark light').addClass(default_header_style); - } - } - - }, { offset: function(){ - return -$j(this).outerHeight() + paspartu_bottom_add; - } }); - } -} - -/* - ** Image Gallery Slider with no space initialization - */ -function initImageGallerySliderNoSpace(){ - if($j('.qode_image_gallery_no_space').length){ - $j('.qode_image_gallery_no_space').each(function(){ - $j(this).animate({'opacity': 1},1000); - $j(this).find('.qode_image_gallery_holder').lemmonSlider({infinite: true}); - }); - - //disable click on non active image - $j('.qode_image_gallery_no_space').on('click', 'li:not(.active) a', function() { - return false; - }); - } -} - -/* - ** Vertical Split Slider - */ - -function initVerticalSplitSlider(){ - "use strict"; - if($j('html').hasClass('vertical_split_screen_initalized')){ - $j('html').removeClass('vertical_split_screen_initalized'); - $j.fn.multiscroll.destroy(); - } - if($j('.vertical_split_slider').length) { - $j('.vertical_split_slider').height($window_height).animate({opacity:1},300); - $j('.vertical_split_slider').multiscroll({ - scrollingSpeed: 500, - navigation: true, - afterRender: function(){ - $j('html').addClass('vertical_split_screen_initalized'); - initButtonHover(); // this function need to be initialized after initVerticalSplitSlider - if($j('div.wpcf7 > form').length){$j('div.wpcf7 > form').wpcf7InitForm();} // this function need to be initialized after initVerticalSplitSlider in order to initialize - initCountdown(); - - if ($j('body').hasClass('vss_responsive_adv')){ - //prepare html for smaller screens - start // - var vertical_split_slider_responsive = $j("
      "); - $j(".vertical_split_slider").after(vertical_split_slider_responsive); - var left_side = $j('.vertical_split_slider .ms-left > div'); - - var right_side = $j('.vertical_split_slider .ms-right > div'); - for(var i = 0; i < left_side.length; i++){ - vertical_split_slider_responsive.append($j(left_side[i]).clone(true)); - vertical_split_slider_responsive.append($j(right_side[left_side.length-1-i]).clone(true)); - } - } - - } - }); - - if ($j('body').hasClass('vss_responsive_adv')){ - if($window_width < 768){ - $j.fn.multiscroll.destroy(); - $j('html,body').css('height', 'auto').css('overflow', 'auto'); - }else{ - $j.fn.multiscroll.build(); - $j('html,body').css('height', '100%').css('overflow', 'hidden'); - } - - $j(window).resize(function() { - if($window_width < 768){ - $j.fn.multiscroll.destroy(); - $j('html,body').css('height', 'auto').css('overflow', 'auto'); - }else{ - $j.fn.multiscroll.build(); - $j('html,body').css('height', '100%').css('overflow', 'hidden'); - } - }); - } - - }else{ - if(!$j('.full_screen_holder').length) { //because this is not necessary on pages if there are full screen sections - $j('html,body').css('height', 'auto').css('overflow', 'auto'); - } - } -} - -/* -** Show Google Map -*/ -function showGoogleMap(){ - "use strict"; - - if($j('.qode_google_map').length){ - $j('.qode_google_map').each(function(){ - - var custom_map_style; - if(typeof $j(this).data('custom-map-style') !== 'undefined') { - custom_map_style = $j(this).data('custom-map-style'); - } - - var color_overlay; - if(typeof $j(this).data('color-overlay') !== 'undefined' && $j(this).data('color-overlay') !== false) { - color_overlay = $j(this).data('color-overlay'); - } - - var saturation; - if(typeof $j(this).data('saturation') !== 'undefined' && $j(this).data('saturation') !== false) { - saturation = $j(this).data('saturation'); - } - - var lightness; - if(typeof $j(this).data('lightness') !== 'undefined' && $j(this).data('lightness') !== false) { - lightness = $j(this).data('lightness'); - } - - var zoom; - if(typeof $j(this).data('zoom') !== 'undefined' && $j(this).data('zoom') !== false) { - zoom = $j(this).data('zoom'); - } - - var pin; - if(typeof $j(this).data('pin') !== 'undefined' && $j(this).data('pin') !== false) { - pin = $j(this).data('pin'); - } - - var map_height; - if(typeof $j(this).data('map-height') !== 'undefined' && $j(this).data('map-height') !== false) { - map_height = $j(this).data('map-height'); - } - - var unique_id; - if(typeof $j(this).data('unique-id') !== 'undefined' && $j(this).data('unique-id') !== false) { - unique_id = $j(this).data('unique-id'); - } - - var google_maps_scroll_wheel; - if(typeof $j(this).data('google-maps-scroll-wheel') !== 'undefined') { - google_maps_scroll_wheel = $j(this).data('google-maps-scroll-wheel'); - } - var addresses; - if(typeof $j(this).data('addresses') !== 'undefined' && $j(this).data('addresses') !== false) { - addresses = $j(this).data('addresses'); - } - - - var map = "map_"+ unique_id; - var geocoder = "geocoder_"+ unique_id; - var holderId = "map_canvas_"+ unique_id; - - initializeGoogleMap(custom_map_style, color_overlay, saturation, lightness, google_maps_scroll_wheel, zoom, holderId, map_height, pin, map, geocoder, addresses) - }); - } - -} -/* - ** Init Google Map - */ -function initializeGoogleMap(custom_map_style, color, saturation, lightness, wheel, zoom, holderId, height, pin, map, geocoder, data){ - "use strict"; - - var mapStyles = [ - { - stylers: [ - {hue: color }, - {saturation: saturation}, - {lightness: lightness}, - {gamma: 1} - ] - } - ]; - - var google_map_type_id; - - if(custom_map_style){ - google_map_type_id = 'qode_style' - } else { - google_map_type_id = google.maps.MapTypeId.ROADMAP - } - - var qodeMapType = new google.maps.StyledMapType(mapStyles, - {name: "Qode Google Map"}); - - geocoder = new google.maps.Geocoder(); - var latlng = new google.maps.LatLng(-34.397, 150.644); - - var myOptions = { - - zoom: zoom, - scrollwheel: wheel, - center: latlng, - zoomControl: true, - zoomControlOptions: { - style: google.maps.ZoomControlStyle.SMALL, - position: google.maps.ControlPosition.RIGHT_CENTER - }, - scaleControl: false, - scaleControlOptions: { - position: google.maps.ControlPosition.LEFT_CENTER - }, - streetViewControl: false, - streetViewControlOptions: { - position: google.maps.ControlPosition.LEFT_CENTER - }, - panControl: false, - panControlOptions: { - position: google.maps.ControlPosition.LEFT_CENTER - }, - mapTypeControl: false, - mapTypeControlOptions: { - mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'qode_style'], - style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, - position: google.maps.ControlPosition.LEFT_CENTER - }, - mapTypeId: google_map_type_id - }; - map = new google.maps.Map(document.getElementById(holderId), myOptions); - map.mapTypes.set('qode_style', qodeMapType); - - var index; - - for (index = 0; index < data.length; ++index) { - initializeGoogleAddress(data[index], pin, map, geocoder); - } - - var holder_element = document.getElementById(holderId); - holder_element.style.height = height + "px"; - - - - -} -/* - ** Init Google Map Addresses - */ -function initializeGoogleAddress(data, pin, map, geocoder){ - "use strict"; - if (data === '') - return; - var contentString = '
      '+ - '
      '+ - '
      '+ - '
      '+ - '

      '+data+'

      '+ - '
      '+ - '
      '; - var infowindow = new google.maps.InfoWindow({ - content: contentString - }); - geocoder.geocode( { 'address': data}, function(results, status) { - if (status === google.maps.GeocoderStatus.OK) { - map.setCenter(results[0].geometry.location); - var marker = new google.maps.Marker({ - map: map, - position: results[0].geometry.location, - icon: pin, - title: data['store_title'] - }); - google.maps.event.addListener(marker, 'click', function() { - infowindow.open(map,marker); - }); - - google.maps.event.addDomListener(window, 'resize', function() { - map.setCenter(results[0].geometry.location); - }); - } - }); -}; - - -function checkSVG(element) { - "use strict"; - - var el = element.find('.active .qode_slide-svg-holder'); - var drawing_enabled = el.data('svg-drawing'); - - if (drawing_enabled === 'yes') { - drawSVG(el); - } -} - -/** - * Function for drawing slider svgs. Based on Codrops article 'SVG Drawing Animation' - */ -function drawSVG(svg){ - "use strict"; - var svgs = Array.prototype.slice.call( svg.find('svg') ), - svgArr = [], - resizeTimeout; - // the svgs already shown... - svgs.forEach( function( el, i ) { - var svg = new SVGEl( el ); - svgArr[i] = svg; - setTimeout(function( el ) { - return function() { - svg.render(); - }; - }( el ), 0 );//0ms pause before drawing - } ); -} -var docElem = window.document.documentElement; -window.requestAnimFrame = function(){ - return ( - window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function(/* function */ callback){ - window.setTimeout(callback, 1000 / 60); - } - ); -}(); -window.cancelAnimFrame = function(){ - return ( - window.cancelAnimationFrame || - window.webkitCancelAnimationFrame || - window.mozCancelAnimationFrame || - window.oCancelAnimationFrame || - window.msCancelAnimationFrame || - function(id){ - window.clearTimeout(id); - } - ); -}(); -function SVGEl( el ) { - this.el = el; - var frameRate = $j(this.el).closest('.qode_slide-svg-holder').data('svg-frames'); - this.image = this.el.previousElementSibling; - this.current_frame = 0; - this.total_frames = frameRate;//number of frames defines speed of drawing - this.path = []; - this.length = []; - this.handle = 0; - this.init(); -} -SVGEl.prototype.init = function() { - var self = this; - [].slice.call( this.el.querySelectorAll( 'path' ) ).forEach( function( path, i ) { - self.path[i] = path; - var l = self.path[i].getTotalLength(); - self.length[i] = l; - self.path[i].style.strokeDasharray = l + ' ' + l; - self.path[i].style.strokeDashoffset = l; - } ); -}; -SVGEl.prototype.render = function() { - if( this.rendered ) return; - this.rendered = true; - this.draw(); -}; -SVGEl.prototype.draw = function() { - var self = this, - progress = this.current_frame/this.total_frames; - if (progress > 1) { - window.cancelAnimFrame(this.handle); - } else { - this.current_frame++; - for(var j=0, len = this.path.length; j 0) { - var skrollr_title = skrollr.init({ - edgeStrategy: 'set', - smoothScrolling: false, - forceHeight: false - }); - skrollr_title.refresh(); - - } -}; - -function initQodeElementAnimationSkrollr() { - "use strict"; - if($j('.no-touch .carousel').length === 0) { - - var elementItemAnimation = $j('.no-touch .q_elements_holder > .q_elements_item'); - elementItemAnimation.each(function(){ - - if((typeof($j(this).data('animation')) !== 'undefined' || typeof($j('.title_outer').data('animation')) !== 'undefined') && $j(this).data('animation') === 'yes') { - var skr = skrollr.init(); - skr.refresh(); - return false; - } - - }); - } - -}; - -function initIconShortcodeHover() { - "use strict"; - - if($j('.qode_icon_shortcode').length) { - - $j('.qode_icon_shortcode').each(function() { - //check if icon type is circle of square - if(typeof $j(this).data('type') !== 'undefined' && ['circle', 'square'].indexOf($j(this).data('type')) != -1) { - - if(typeof $j(this).data('hover-bg-color') !== 'undefined') { - if($j(this).data('type') == 'circle') { - var elementToHover = $j(this).find('i').first(); - var hoverBgColor = $j(this).data('hover-bg-color'); - var initialStyle = elementToHover.attr('style'); - - $j(this).hover(function() { - elementToHover.attr('style', initialStyle + 'color: ' + hoverBgColor + '!important'); - }, function() { - elementToHover.attr('style', initialStyle); - }); - } else { - var hoverBgColor = $j(this).data('hover-bg-color'); - var initialBgColor = $j(this).css('background-color'); - - $j(this).hover(function() { - $j(this).css('background-color', hoverBgColor); - }, function() { - $j(this).css('background-color', initialBgColor); - }); - } - } - } - - if(typeof $j(this).data('hover-icon-color') !== 'undefined') { - var hoverColor = $j(this).data('hover-icon-color'); - var initialColor = $j(this).find('.qode_icon_element ').css('color'); - - $j(this).hover(function() { - $j(this).find('.qode_icon_element ').css('color', hoverColor); - }, function() { - $j(this).find('.qode_icon_element ').css('color', initialColor); - }); - } - }); - } -} - -function initIconWithTextHover() { - "use strict"; - - if($j('.qode_iwt_icon_holder').length) { - $j('.qode_iwt_icon_holder').each(function() { - if(typeof $j(this).data('icon-hover-bg-color') !== 'undefined') { - var hoverBgColor = $j(this).data('icon-hover-bg-color'); - var initialBgColor = $j(this).css('background-color'); - - $j(this).hover(function() { - $j(this).css('background-color', hoverBgColor); - }, function() { - $j(this).css('background-color', initialBgColor); - }); - } - - if(typeof $j(this).data('icon-hover-color') !== 'undefined') { - var elementToChange = $j(this).find('.qode_iwt_icon_element'); - var hoverColor = $j(this).data('icon-hover-color'); - var initialColor = elementToChange.css('color'); - - $j(this).hover(function() { - elementToChange.css('color', hoverColor); - }, function() { - elementToChange.css('color', initialColor); - }); - } - }); - } -} - -function initLoadNextPostOnBottom(){ - "use strict"; - - if($j('.blog_vertical_loop').length) { - var header_addition; - var normal_header_addition; - var paspartu_add = $j('body').hasClass('paspartu_enabled') ? Math.round($window_width*paspartu_width) : 0; - - if($j('header.page_header').hasClass('transparent')) { - normal_header_addition = 0; - }else{ - normal_header_addition = header_height; - } - - var click = true; - - var $container = $j('.blog_vertical_loop .blog_holder'); - $j(document).on('click','.blog_vertical_loop_button a',function(e){ - e.preventDefault(); - if(click){ - click = false; - var $this = $j(this); - - var link = $this.attr('href'); - var $content = '.blog_vertical_loop .blog_holder'; - var $anchor = '.blog_vertical_loop_button_holder a'; - var $next_href = $j($anchor).attr('href'); - - //check for mobile header - if($window_width < 1000){ - header_addition = $j('header.page_header').height(); - }else{ - header_addition = normal_header_addition; - } - - var scrollTop = $j(window).scrollTop(), - elementOffset = $this.closest('article').offset().top, - distance = (elementOffset - scrollTop) - header_addition - paspartu_add; - - $container.find('article:eq(1)').addClass('fade_out'); - $this.closest('article').addClass('move_up').removeClass('next_post').css('transform', 'translateY(-' + distance + 'px)'); - setTimeout(function () { - $j(window).scrollTop(0); - $container.find('article:eq(0)').remove(); - $container.find('article:eq(0)').addClass('previous_post'); - $this.closest('article').removeAttr('style').removeClass('move_up'); - }, 450); - - - $j.get(link + '', function (data) { - var $new_content = $j(data).find('article').addClass('next_post'); - $next_href = $j($anchor, data).attr('href'); - $container.append($j($new_content)); - click = true; - }); - } - else{ - return false; - } - }); - - $j(document).on('click','.blog_vertical_loop_back_button a',function(e){ - e.preventDefault(); - if(click){ - click = false; - var $this = $j(this); - - var link = $this.attr('href'); - var $content = '.blog_vertical_loop .blog_holder'; - var $anchor = '.blog_vertical_loop_button_holder.prev_post a'; - var $prev_href = $j($anchor).attr('href'); - - $container.find('article:eq(0)').removeClass('fade_out').addClass('fade_in'); - $this.closest('article').addClass('move_up').css('transform', 'translateY(' + $window_height + 'px)'); - setTimeout(function () { - $container.find('article:last-child').remove(); - $container.find('article:eq(0)').removeClass('previous_post fade_in'); - $this.closest('article').addClass('next_post').removeAttr('style').removeClass('move_up'); - - $j.get(link + '', function (data) { - var $new_content = $j(data).find('article').removeClass('next_post').addClass('previous_post'); //by default, posts have next_post class - $prev_href = $j($anchor, data).attr('href'); - $container.prepend($j($new_content)); - click = true; - }); - - }, 450); - - }else{ - return false; - } - - }); - - //load previous post on page load - $j.get($j('.blog_vertical_loop_button_holder .last_page a').attr('href') + '', function (data) { - var $new_content = $j(data).find('article').removeClass('next_post').addClass('previous_post'); //by default, posts have next_post class - $container.prepend($j($new_content)); - }); - //load next post on page load - $j.get($j('.blog_vertical_loop_button a').attr('href') + '', function (data) { - var $new_content = $j(data).find('article').addClass('next_post'); - $container.append($j($new_content)); - }); - } -} - -/* - Parallax Layers plugin - */ - -(function ( $ ) { - "use strict"; - - $.fn.extend({ - - mouseParallax: function(options) { - - var defaults = { moveFactor: 1.5, targetContainer: this }; - - var options = $.extend(defaults, options); - - return this.each(function() { - var o = options; - var layer_elements = $(o.targetContainer).find('.image, .paralax_layers_content_holder'); - - layer_elements.each(function(i){ - $(this).css('z-index',i); - }); - - var mouseXStart; - var mouseYStart; - - mouseXStart = $(o.targetContainer).offset().left; - mouseYStart = $(o.targetContainer).offset().top; - - $(o.targetContainer).on('mouseenter',function(e){ - mouseXStart = e.pageX - $(this).offset().left; - mouseYStart = e.pageY - $(this).offset().top; - }); - - $(o.targetContainer).on('mousemove', function(e){ - - var mouseX0 = $(this).offset().left + mouseXStart; - var mouseY0 = $(this).offset().top + mouseYStart; - - var mouseX = e.pageX - mouseX0; - var mouseY = e.pageY - mouseY0; - - layer_elements.each(function(i){ - $(this).css({ - marginLeft : -mouseX / 100 * o.moveFactor*(i+1), - marginTop : -mouseY / 100 * o.moveFactor*(i+1) - },100); - }); - }); - var config = { - interval: 0, - over: function(){}, - timeout: 500, - out: function(){ - layer_elements.each(function(i){ - $(this).stop().animate({ - marginLeft: 0, - marginTop: 0 - },300); - }); - } - }; - - $(o.targetContainer).hoverIntent(config); - - }); - } - - - }); -} (jQuery) ); - -/** - * Initialize parallax layers function - */ - -function setParallaxLayersHeight($this, $def_height){ - "use strict"; - - var parallax_layers_height = $def_height; - var responsive_breakpoint_set = [1600,1300,1000,768,567,320]; - if($window_width > responsive_breakpoint_set[0]){ - parallax_layers_height = $def_height; - }else if($window_width > responsive_breakpoint_set[1]){ - parallax_layers_height = $def_height * 0.75; - }else if($window_width > responsive_breakpoint_set[2]){ - parallax_layers_height = $def_height * 0.6; - }else if($window_width > responsive_breakpoint_set[3]){ - parallax_layers_height = $def_height * 0.55; - }else if($window_width <= responsive_breakpoint_set[3]){ - parallax_layers_height = $def_height * 0.45; - } - - $this.css({'height': (parallax_layers_height) + 'px'}); -} - -function parallaxLayers(){ - "use strict"; - - if($j('.qode_parallax_layers').length){ - - $j(".qode_parallax_layers").each(function(){ - - var $this = $j(this); - if($j(this).hasClass('full_screen_height')){ - $this.height($window_height); - $j(window).resize(function () { - $this.height($window_height); - }); - }else{ - var $def_height = $j(this).data('height'); - setParallaxLayersHeight($this, $def_height); - $j(window).resize(function () { - setParallaxLayersHeight($this, $def_height); - }); - } - - var $parallax_layers_holder = $this.find('.qode_parallax_layers_holder'); - var counter = 0; - var limit = $this.find(".image").length; - $this.find(".image").each(function() { - - var $this = $j(this); - if($this.css("background-image") != "" && $this.css("background-image") != "none") { - - var bg_url = $this.attr('style'); - - bg_url = bg_url.match(/url\(["']?([^'")]+)['"]?\)/); - bg_url = bg_url ? bg_url[1] : ""; - if (bg_url) { - var backImg = new Image(); - backImg.src = bg_url; - $j(backImg).load(function(){ - counter++; - if(counter == limit){ - $parallax_layers_holder.removeClass('preload_parallax_layers'); - if($j('html').hasClass('no-touch')){$parallax_layers_holder.mouseParallax()}; - } - }); - } - } - }); - }); - - } -} - -function alterWPMLSwitcherHeaderBottom() { - "use strict"; - - if($j('.header_bottom .main_menu li.menu-item-language').length) { - var langDropdown = $j('.header_bottom .main_menu .menu-item-language').find('.submenu-languages'); - - if(typeof langDropdown !== 'undefined') { - langDropdown.parent('li').addClass('narrow'); - langDropdown.wrap('
      '); - langDropdown.show(); - } - } - - if($j('.header_bottom .mobile_menu li.menu-item-language').length) { - var langDropdown = $j('.header_bottom .mobile_menu .menu-item-language').find('.submenu-languages'); - - if(typeof langDropdown !== 'undefined') { - langDropdown.parent('li').addClass('has_sub'); - langDropdown.prev('a').after(''); - langDropdown.addClass('sub_menu'); - } - - } -} diff --git a/core/docs/sources-asciidoc/src/main/asciidoc/stylesheets/telestax.css~ b/core/docs/sources-asciidoc/src/main/asciidoc/stylesheets/telestax.css~ deleted file mode 100644 index 08f89a04f..000000000 --- a/core/docs/sources-asciidoc/src/main/asciidoc/stylesheets/telestax.css~ +++ /dev/null @@ -1,22471 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Varela+Round|Open+Sans:400italic,600italic,400,600|Ubuntu+Mono:400); -/*! normalize.css v2.1.2 | MIT License | git.io/normalize */ -/* ========================================================================== HTML5 display definitions ========================================================================== */ -/** Correct `block` display not defined in IE 8/9. */ -article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; } - -/** Correct `inline-block` display not defined in IE 8/9. */ -audio, canvas, video { display: inline-block; } - -/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */ -audio:not([controls]) { display: none; height: 0; } - -/** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */ -[hidden], template { display: none; } - -script { display: none !important; } - -/* ========================================================================== Base ========================================================================== */ -/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */ - -/** Remove default margin. */ -body { margin: 0; } - -/* ========================================================================== Links ========================================================================== */ -/** Remove the gray background color from active links in IE 10. */ -a { background: transparent; } - -/** Address `outline` inconsistency between Chrome and other browsers. */ -a:focus { outline: thin dotted; } - -/** Improve readability when focused and also mouse hovered in all browsers. */ -a:active, a:hover { outline: 0; } - -/* ========================================================================== Typography ========================================================================== */ -/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */ -h1 { font-size: 2em; margin: 0.67em 0; } - -/** Address styling not present in IE 8/9, Safari 5, and Chrome. */ -abbr[title] { border-bottom: 1px dotted; } - -/** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */ -b, strong { font-weight: bold; } - -/** Address styling not present in Safari 5 and Chrome. */ -dfn { font-style: italic; } - -/** Address differences between Firefox and other browsers. */ -hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; } - -/** Address styling not present in IE 8/9. */ -mark { background: #ff0; color: #000; } - -/** Correct font family set oddly in Safari 5 and Chrome. */ -code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } - -/** Improve readability of pre-formatted text in all browsers. */ -pre { white-space: pre-wrap; } - -/** Set consistent quote types. */ -q { quotes: "\201C" "\201D" "\2018" "\2019"; } - -/** Address inconsistent and variable font size in all browsers. */ -small { font-size: 80%; } - -/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */ -sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } - -sup { top: -0.5em; } - -sub { bottom: -0.25em; } - -/* ========================================================================== Embedded content ========================================================================== */ -/** Remove border when inside `a` element in IE 8/9. */ -img { border: 0; } - -/** Correct overflow displayed oddly in IE 9. */ -svg:not(:root) { overflow: hidden; } - -/* ========================================================================== Figures ========================================================================== */ -/** Address margin not present in IE 8/9 and Safari 5. */ -figure { margin: 0; } - -/* ========================================================================== Forms ========================================================================== */ -/** Define consistent border, margin, and padding. */ -fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } - -/** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */ -legend { border: 0; /* 1 */ padding: 0; /* 2 */ } - -/** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */ -button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ } - -/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */ -button, input { line-height: normal; } - -/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */ -button, select { text-transform: none; } - -/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */ -button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ } - -/** Re-set default cursor for disabled elements. */ -button[disabled], html input[disabled] { cursor: default; } - -/** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */ -input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } - -/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */ -input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; } - -/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */ -input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } - -/** Remove inner padding and border in Firefox 4+. */ -button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } - -/** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */ -textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ } - -/* ========================================================================== Tables ========================================================================== */ -/** Remove most spacing between table cells. */ -table { border-collapse: collapse; border-spacing: 0; } - -meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; } - -meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; } - -meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; } - -*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } - -html, body { font-size: 100%; } - -body { background: #fefdfd; color: rgba(0, 0, 0, 0.8); padding: 0; margin: 0; font-family: "Open Sans", sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; } - -a:hover { cursor: pointer; } - -img, object, embed { height: 100%; width: 100%; max-width: 100%; height: auto; } - -object, embed { height: 100%; } - -img { -ms-interpolation-mode: bicubic; } - -#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; } - -.left { float: left !important; } - -.right { float: right !important; } - -.text-left { text-align: left !important; } - -.text-right { text-align: right !important; } - -.text-center { text-align: center !important; } - -.text-justify { text-align: justify !important; } - -.hide { display: none; } - -.antialiased, body { -webkit-font-smoothing: antialiased; } - -img { display: inline-block; vertical-align: middle; } - -textarea { height: auto; min-height: 50px; } - -select { width: 100%; } - -object, svg { display: inline-block; vertical-align: middle; } - -.center { margin-left: auto; margin-right: auto; } - -.spread { width: 100%; } - -p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; } - -.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.25; color: #002c5e; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; } - -/* Typography resets */ -div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; } - -/* Default Link Styles */ -a { color: #005580; text-decoration: underline; line-height: inherit; } -a:hover, a:focus { color: #078d71; } -a img { border: none; } - -/* Default paragraph styles */ -p { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; text-rendering: optimizeLegibility; } -p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; } - -/* Default header styles */ -h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: "Varela Round", sans-serif; font-weight: 400; font-style: normal; color: #00326b; text-rendering: optimizeLegibility; margin-top: 0.8em; margin-bottom: 0.5em; line-height: 1.0625em; } -h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small {color: #057aff; line-height: 0; } - -h1 { font-size: 2.125em; } - -h2 { font-size: 1.6875em; } - -h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; } - -h4 { font-size: 1.125em; } - -h5 { font-size: 1.125em; } - -h6 { font-size: 1em; } - -hr { border: solid rgba(145, 135, 84, 0.15); border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; } - -/* Helpful Typography Defaults */ -em, i { font-style: italic; line-height: inherit; } - -strong, b { font-weight: bold; line-height: inherit; } - -small { font-size: 60%; line-height: inherit; } - -code { font-family: "Ubuntu Mono", "Inconsolata", monospace; font-weight: 400; color: #331d00; } - -/* Lists */ -ul, ol, dl { font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; } - -ul, ol { margin-left: 1.5em; } -ul.no-bullet, ol.no-bullet { margin-left: 1.5em; } - -/* Unordered Lists */ -ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ } -ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; } -ul.square { list-style-type: square; } -ul.circle { list-style-type: circle; } -ul.disc { list-style-type: disc; } -ul.no-bullet { list-style: none; } - -/* Ordered Lists */ -ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; } - -/* Definition Lists */ -dl dt { margin-bottom: 0.3125em; font-weight: bold; } -dl dd { margin-bottom: 1.25em; } - -/* Abbreviations */ -abbr, acronym { text-transform: uppercase; font-size: 90%; color: rgba(0, 0, 0, 0.8); border-bottom: 1px dotted #dddddd; cursor: help; } - -abbr { text-transform: none; } - -/* Blockquotes */ -blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; } -blockquote cite { display: block; font-size: 0.8125em; color: #666666; } -blockquote cite:before { content: "\2014 \0020"; } -blockquote cite a, blockquote cite a:visited { color: #666666; } - -blockquote, blockquote p { line-height: 1.5; color: #999999; } - -/* Microformats */ -.vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; } -.vcard li { margin: 0; display: block; } -.vcard .fn { font-weight: bold; font-size: 0.9375em; } - -.vevent .summary { font-weight: bold; } -.vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; } - -@media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.25; } - h1 { font-size: 2.75em; } - h2 { font-size: 2.3125em; } - h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; } - h4 { font-size: 1.4375em; } } -/* Tables */ -table { background: white; margin-bottom: 1.25em; border: solid 1px rgba(145, 135, 84, 0.15); } -table thead, table tfoot { background: rgba(119, 84, 22, 0.1); font-weight: bold; } -table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: rgba(0, 0, 0, 0.8); text-align: left; } -table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: rgba(0, 0, 0, 0.8); } -table tr.even, table tr.alt, table tr:nth-of-type(even) { background: rgba(119, 84, 22, 0.025); } -table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.5; } - -body { tab-size: 4; } - -h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.25; } - -.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; } -.clearfix:after, .float-group:after { clear: both; } - -*:not(pre) > code { font-size: 0.86667em; font-style: normal !important; letter-spacing: 0; padding: 1px 5px 1px 5px; background-color: transparent; border: 1px solid #dddddd; -webkit-border-radius: 3px; border-radius: 3px; line-height: inherit; } - -pre, pre > code { line-height: 1.6; color: white; font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; } - -.keyseq { color: rgba(51, 51, 51, 0.8); } - -kbd { font-family: "Ubuntu Mono", "Inconsolata", monospace; display: inline-block; color: rgba(0, 0, 0, 0.8); font-size: 0.65em; line-height: 1.45; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: 0 0.15em; padding: 0.2em 0.5em; vertical-align: middle; position: relative; top: -0.1em; white-space: nowrap; } - -.keyseq kbd:first-child { margin-left: 0; } - -.keyseq kbd:last-child { margin-right: 0; } - -.menuseq, .menu { color: rgba(0, 0, 0, 0.8); } - -b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; } - -b.button:before { content: "["; padding: 0 3px 0 2px; } - -b.button:after { content: "]"; padding: 0 2px 0 3px; } - -p a > code:hover { color: #1a0f00; } - -#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; } -#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; } -#header:after, #content:after, #footnotes:after, #footer:after { clear: both; } - -#content { margin-top: 1.25em; } - -#content:before { content: none; } - -#header > h1:first-child { color: #703f1c; margin-top: 2.25rem; margin-bottom: 0; } -#header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid rgba(145, 135, 84, 0.15); } -#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid rgba(145, 135, 84, 0.15); padding-bottom: 8px; } -#header .details { border-bottom: 1px solid rgba(145, 135, 84, 0.15); line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #666666; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; } -#header .details span:first-child { margin-left: -0.125em; } -#header .details span.email a { color: #999999; } -#header .details br { display: none; } -#header .details br + span:before { content: "\00a0\2013\00a0"; } -#header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #999999; } -#header .details br + span#revremark:before { content: "\00a0|\00a0"; } -#header #revnumber { text-transform: capitalize; } -#header #revnumber:after { content: "\00a0"; } - -#content > h1:first-child:not([class]) { color: #703f1c; border-bottom: 1px solid rgba(145, 135, 84, 0.15); padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; } - -#toc { border-bottom: 0px solid #dddddd; padding-bottom: 0.5em; } -#toc > ul { margin-left: 0.125em; } -#toc ul.sectlevel0 > li > a { font-style: italic; } -#toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; } -#toc ul { font-family: "Varela Round", sans-serif; list-style-type: none; } -#toc li { line-height: 1.3334; margin-top: 0.3334em; } -#toc a { text-decoration: none; } -#toc a:active { text-decoration: underline; } - -#toctitle { color: #002c5e; font-size: 1.2em; } - -@media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; } - body.toc2 { padding-left: 15em; padding-right: 0; } - #toc.toc2 { margin-top: 0 !important; background-color: #f2f2f4; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #dddddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; } - #toc.toc2 #toctitle { margin-top: 0; margin-bottom: 0.8rem; font-size: 1.2em; } - #toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; } - #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; } - #toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; } - body.toc2.toc-right { padding-left: 0; padding-right: 15em; } - body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #dddddd; left: auto; right: 0; } } -@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; } - #toc.toc2 { width: 20em; } - #toc.toc2 #toctitle { font-size: 1.375em; } - #toc.toc2 > ul { font-size: 0.95em; } - #toc.toc2 ul ul { padding-left: 1.25em; } - body.toc2.toc-right { padding-left: 0; padding-right: 20em; } } -#content #toc { border-style: solid; border-width: 1px; border-color: #d6d6dd; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f4; -webkit-border-radius: 6px; border-radius: 6px; } -#content #toc > :first-child { margin-top: 0; } -#content #toc > :last-child { margin-bottom: 0; } - -#footer { max-width: 100%; background-color: #0b445a; padding: 1.25em; } - -#footer-text { color: #fefdfd; line-height: 1.35; } - -.sect1 { padding-bottom: 0.625em; } - -@media only screen and (min-width: 768px) { .sect1 { padding-bottom: 1.25em; } } -.sect1 + .sect1 { border-top: 0px solid #dddddd; } - -#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; } -#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\00A7"; display: block; padding-top: 0.1em; } -#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; } -#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #00326b; text-decoration: none; } -#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #002652; } - -.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; } - -.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; } - -table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; } - -.paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: #703f1c; } - -table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; } -content > img { width:100%; height:100%; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; } - -.admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; } -.admonitionblock > table td.icon { vertical-align: middle; text-align: center; width: 80px; } -.admonitionblock > table td.icon img { max-width: none; } -.admonitionblock > table td.icon .title { font-weight: bold; font-family: "Varela Round", sans-serif; text-transform: uppercase; } -.admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid rgba(145, 135, 84, 0.15); color: #666666; text-align: left;} -.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; } - -.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #eddbdb; margin-bottom: 1.25em; padding: 1.25em; background: #fefdfd; -webkit-border-radius: 6px; border-radius: 6px; } -.exampleblock > .content > :first-child { margin-top: 0; } -.exampleblock > .content > :last-child { margin-bottom: 0; } - -.sidebarblock { border-style: solid; border-width: 1px; border-color: #d6d6dd; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f4; -webkit-border-radius: 6px; border-radius: 6px; } -.sidebarblock > :first-child { margin-top: 0; } -.sidebarblock > :last-child { margin-bottom: 0; } -.sidebarblock > .content > .title { color: #002c5e; margin-top: 0; } - -.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; } - -.literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: rgba(16, 195, 196, 0.05); } -.sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; } - -.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px solid rgba(16, 195, 196, 0.125); -webkit-border-radius: 6px; border-radius: 6px; word-wrap: break-word; padding: 1em; font-size: 0.8125em; } -.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; } -@media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } } -@media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } } - -.literalblock.output pre { color: rgba(16, 195, 196, 0.05); background-color: inherit; } -.literalblock > .content pre, .listingblock > .content pre { background: #333333; border-width: 2px; border-style: solid; border-color: #dddddd; -webkit-border-radius: 3px; border-radius: 3px; padding: 0.66667em; word-wrap: break-word; } - -.listingblock pre.highlightjs { padding: 0; } -.listingblock pre.highlightjs > code { padding: 1em; -webkit-border-radius: 6px; border-radius: 6px; } - -/*.listingblock > .content { position: relative; }*/ -.listingblock > .content pre, .listingblock > .content pre { background: #333333; border-width: 2px; border-style: solid; border-color: #dddddd; -webkit-border-radius: 3px; border-radius: 3px; padding: 0.66667em; word-wrap: break-word; } - -.listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; } - -.listingblock:hover code[data-lang]:before { display: block; } - -.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; } - -.listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; } - -table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; } - -table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; line-height: 1.4; } - -table.pyhltable td.code { padding-left: .75em; padding-right: 0; } - -pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid rgba(145, 135, 84, 0.15); } - -pre.pygments .lineno { display: inline-block; margin-right: .25em; } - -table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; } - -.quoteblock { margin: 0 1em 1.25em 1.5em; display: table; } -.quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; } -.quoteblock blockquote, .quoteblock blockquote p { color: #999999; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; } -.quoteblock blockquote { margin: 0; padding: 0; border: 0; } -.quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #002c5e; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } -.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; } -.quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; } -.quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #666666; } -.quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; } -.quoteblock .quoteblock blockquote:before { display: none; } - -.verseblock { margin: 0 1em 1.25em 1em; } -.verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #999999; font-weight: 300; text-rendering: optimizeLegibility; } -.verseblock pre strong { font-weight: 400; } -.verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; } - -.quoteblock .attribution, .verseblock .attribution { font-size: 0.8125em; line-height: 1.45; font-style: italic; } -.quoteblock .attribution br, .verseblock .attribution br { display: none; } -.quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.025em; color: #666666; } - -.quoteblock.abstract { margin: 0 0 1.25em 0; display: block; } -.quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; } -.quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; } - -table.tableblock { max-width: 100%; border-collapse: separate; } -table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; } - -table.tableblock, th.tableblock, td.tableblock { border: 0 solid rgba(145, 135, 84, 0.15); } - -table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; } - -table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; } - -table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; } - -table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; } - -table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; } - -table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; } - -table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; } - -table.frame-all { border-width: 1px; } - -table.frame-sides { border-width: 0 1px; } - -table.frame-topbot { border-width: 1px 0; } - -th.halign-left, td.halign-left { text-align: left; } - -th.halign-right, td.halign-right { text-align: right; } - -th.halign-center, td.halign-center { text-align: center; } - -th.valign-top, td.valign-top { vertical-align: top; } - -th.valign-bottom, td.valign-bottom { vertical-align: bottom; } - -th.valign-middle, td.valign-middle { vertical-align: middle; } - -table thead th, table tfoot th { font-weight: bold; } - -tbody tr th { display: table-cell; line-height: 1.5; background: rgba(119, 84, 22, 0.1); } - -tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: rgba(0, 0, 0, 0.8); font-weight: bold; } - -p.tableblock > code:only-child { background: none; padding: 0; } - -p.tableblock { font-size: 1em; } - -td > div.verse { white-space: pre; } - -ol { margin-left: 1.75em; } - -ul li ol { margin-left: 1.5em; } - -dl dd { margin-left: 1.125em; } - -dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; } - -ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.625em; } - -ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; } - -ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; } - -ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1em; font-size: 0.85em; } - -ul.checklist li > p:first-child > input[type="checkbox"]:first-child { width: 1em; position: relative; top: 1px; } - -ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; } -ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; } -ul.inline > li > * { display: block; } - -.unstyled dl dt { font-weight: normal; font-style: normal; } - -ol.arabic { list-style-type: decimal; } - -ol.decimal { list-style-type: decimal-leading-zero; } - -ol.loweralpha { list-style-type: lower-alpha; } - -ol.upperalpha { list-style-type: upper-alpha; } - -ol.lowerroman { list-style-type: lower-roman; } - -ol.upperroman { list-style-type: upper-roman; } - -ol.lowergreek { list-style-type: lower-greek; } - -.hdlist > table, .colist > table { border: 0; background: none; } -.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; } - -td.hdlist1, td.hdlist2 { vertical-align: top; padding: 0 0.625em; } - -td.hdlist1 { font-weight: bold; padding-bottom: 1.25em; } - -.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; } - -.colist > table tr > td:first-of-type { padding: 0 0.75em; line-height: 1; } -.colist > table tr > td:last-of-type { padding: 0.25em 0; } - -.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; } - -.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; } -.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; } -.imageblock > .title { margin-bottom: 0; } -.imageblock.thumb, .imageblock.th { border-width: 6px; } -.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; } - -.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; } -.image.left { margin-right: 0.625em; } -.image.right { margin-left: 0.625em; } - -a.image { text-decoration: none; display: inline-block; } -a.image object { pointer-events: none; } - -sup.footnote, sup.footnoteref { font-size: 0.875em; position: static; vertical-align: super; } -sup.footnote a, sup.footnoteref a { text-decoration: none; } -sup.footnote a:active, sup.footnoteref a:active { text-decoration: underline; } - -#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; } -#footnotes hr { width: 20%; min-width: 6.25em; margin: -0.25em 0 0.75em 0; border-width: 1px 0 0 0; } -#footnotes .footnote { padding: 0 0.375em 0 0.225em; line-height: 1.3334; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.05em; margin-bottom: 0.2em; } -#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; } -#footnotes .footnote:last-of-type { margin-bottom: 0; } - -#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; } - -.gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; } -.gist .file-data > table td.line-data { width: 99%; } - -div.unbreakable { page-break-inside: avoid; } - -.big { font-size: larger; } - -.small { font-size: smaller; } - -.underline { text-decoration: underline; } - -.overline { text-decoration: overline; } - -.line-through { text-decoration: line-through; } - -.aqua { color: #00bfbf; } - -.aqua-background { background-color: #00fafa; } - -.black { color: black; } - -.black-background { background-color: black; } - -.blue { color: #0000bf; } - -.blue-background { background-color: #0000fa; } - -.fuchsia { color: #bf00bf; } - -.fuchsia-background { background-color: #fa00fa; } - -.gray { color: #606060; } - -.gray-background { background-color: #7d7d7d; } - -.green { color: #006000; } - -.green-background { background-color: #007d00; } - -.lime { color: #00bf00; } - -.lime-background { background-color: #00fa00; } - -.maroon { color: #600000; } - -.maroon-background { background-color: #7d0000; } - -.navy { color: #000060; } - -.navy-background { background-color: #00007d; } - -.olive { color: #606000; } - -.olive-background { background-color: #7d7d00; } - -.purple { color: #600060; } - -.purple-background { background-color: #7d007d; } - -.red { color: #bf0000; } - -.red-background { background-color: #fa0000; } - -.silver { color: #909090; } - -.silver-background { background-color: #bcbcbc; } - -.teal { color: #006060; } - -.teal-background { background-color: #007d7d; } - -.white { color: #bfbfbf; } - -.white-background { background-color: #fafafa; } - -.yellow { color: #bfbf00; } - -.yellow-background { background-color: #fafa00; } - -span.icon > .fa { cursor: default; } - -.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; } -.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #004060; } -.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; } -.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; } -.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; } -.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; } - -.conum[data-value] { display: inline-block; color: #fff !important; background-color: rgba(0, 0, 0, 0.8); -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; } -.conum[data-value] * { color: #fff !important; } -.conum[data-value] + b { display: none; } -.conum[data-value]:after { content: attr(data-value); } -pre .conum[data-value] { position: relative; top: -0.125em; } - -b.conum * { color: inherit !important; } - -.conum:not([data-value]):empty { display: none; } - -#toc.toc2 ul ul { list-style-type: circle; padding-left: 2em; } - -.sect1 { padding-bottom: 0 !important; margin-bottom: 2.5em; } - -#header h1 { font-weight: bold; position: relative; left: -0.0625em; } - -#content h2, #content h3, #content #toctitle, #content .sidebarblock > .content > .title, #content h4, #content h5, #content #toctitle { position: relative; left: -0.0625em; } -#content h2 { font-weight: bold; } - -.paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: black; } - -pre.pygments.highlight { background-color: rgba(16, 195, 196, 0.05); } - -.pygments .tok-err { border: none !important; color: #800000 !important; } - -.pygments .tok-c { color: #999 !important; } - - - - -/*Telestax stylesheet.css */ -.wp-caption, -.wp-caption-text, -.sticky, -.gallery-caption, -.bypostauthor{ - opacity: 1; -} - -.clearfix:before, -.clearfix:after { - content: " "; /* 1 */ - display: table; /* 2 */ -} - -.clearfix:after { - clear: both; -} - -.clearfix { - *zoom: 1; -} - -.clear:after { - clear: both; - content: ""; - display: block; -} - -/* Webkit */ -::selection { - background: #f25f33; - color: #fff; -} -/* Gecko/Mozilla */ -::-moz-selection { - background: #f25f33 - color: #fff; -} - -.alignleft { - float: left; - margin: 0 20px 20px 0; -} -.alignright { - float: right; - margin: 0 0 20px 20px; -} -.aligncenter { - display: block; - margin: 10px auto; -} -.header_top .aligncenter{ - margin: 8px auto; -} -.text-align-right { - text-align: right; -} -.text-align-left { - text-align: left; -} -.text-align-center { - text-align: center; -} - -/*.content ul ul, -.content ol ol{ - padding:0 0 0 15px; -}*/ - -/* =Reset default browser CSS. --------------------------------------------------------------- */ -html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font, - ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td - { - background: transparent; - border: 0; - margin: 0; - padding: 0; - vertical-align: baseline; - outline: none; -} - -article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { - display: block; -} - -blockquote { - quotes: none; -} - -blockquote:before,blockquote:after { - content: ''; - content: none; -} - -del { - text-decoration: line-through; -} - -/* tables still need 'cellspacing="0"' in the markup */ -table { - border-collapse: collapse; - border-spacing: 0; - border: medium none; - vertical-align: middle; -} - -table th{ - border: 0; - padding: 5px 7px; - text-align: center; -} - -table td { - padding: 5px 10px; - text-align: center; -} - -a img { - border: none; -} - -img{ - max-width: 100%; - height: auto; -} - -h1,h2,h3,h4,h5,h6{ - color: #303030; -} - -h1{ - font-size: 30px; - line-height: 1.25em; /* 20px/16px */ -} - -h2{ - font-size: 24px; - line-height: 1.384615384615385em; /* 36px/26px */ - text-transform:uppercase; - letter-spacing:1px; - font-weight: 600; -} - -h3{ - font-size: 17px; - line-height: 1.304347826086957em; /* 30px/23px */ - text-transform:uppercase; - letter-spacing:1px; - font-weight: 600; -} - -h4{ - font-size: 19px; - line-height: 1.375em; /* 22px/16px */ - font-weight: 400; -} - -h5{ - font-size: 15px; - line-height: 1.571428571428571em; /* 22px/14px */ - text-transform:uppercase; - letter-spacing:1px; - font-weight: 600; -} - -h6{ - font-size: 13px; - line-height: 1.538461538461538em; /* 20px/13px */ - text-transform:uppercase; - letter-spacing:1px; - font-weight:600; -} - -h1 a, -h2 a, -h3 a, -h4 a, -h5 a, -h6 a{ - color: #303030; -} - -h1 a:hover, -h2 a:hover, -h3 a:hover, -h4 a:hover, -h5 a:hover, -h6 a:hover{ - color: #1abc9c; -} - -a, -p a{ - color: #303030; - text-decoration: none; - cursor: pointer; -} - -a:hover, -p a:hover { - color: #1abc9c; - text-decoration: none; -} - -input[type='submit'], -.woocommerce input[type='button'], -.woocommerce-page input[type='button']{ - -webkit-appearance: none; -} - -ul{ - list-style-position:inside; -} - -/* =Structure --------------------------------------------------------------- */ - -html{ - height: 100%; - margin: 0px !important; - -webkit-transition: all 1.3s ease-out; - -moz-transition: all 1.3s ease-out; - -o-transition: all 1.3s ease-out; - -ms-transition: all 1.3s ease-out; - transition: all 1.3s ease-out; -} - -body{ - font-family: 'Roboto', sans-serif; - font-size: 16px; - line-height: 26px; - color: #818181; - font-weight: 400; - background-color: #f6f6f6; - overflow-y: scroll; - overflow-x: hidden !important; - -webkit-font-smoothing: antialiased; -} - -.wrapper { - background-color: #f6f6f6; - position: relative; - z-index: 1000; - -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - left: 0px; -} - -.right_side_menu_opened .wrapper{ - left: -270px; -} - -.right_side_menu_opened .wrapper header.fixed, -.right_side_menu_opened .wrapper header.fixed_hiding, -.right_side_menu_opened .wrapper header.sticky, -.right_side_menu_opened .wrapper header.fixed_top_header .top_header{ - left: -270px; -} - -@media only screen and (min-width: 1100px){ - .right_side_menu_opened:not(.boxed) .carousel-inner:not(.relative_position){ - left: -270px !important; - } -} - -.wrapper_inner{ - width: 100%; - overflow: hidden; -} - -body.boxed .wrapper_inner{ - overflow: visible; -} - -body.boxed .content{ - overflow: hidden; -} - -.meta{ - display: none; -} - -.ajax_loader { - position: fixed; - top: 50%; - left: 50%; - z-index: 1100; - display: none; -} - -@media only screen and (min-width: 1000px){ - body.vertical_menu_enabled:not(.vertical_menu_hidden) .ajax_loader{ - margin-left: 130px; - } - - body.vertical_menu_enabled.vertical_menu_hidden .ajax_loader{ - margin-left: 20px; - } -} - -.ajax_loader_1 { - position: relative; - display: inline-block; - width: 100%; - height: 100%; -} - -.ajax_loader_2 { - margin: -50% 0 0 -50%; -} - -/* pulse - start */ - -.ajax_loader .pulse { - width: 32px; - height: 32px; - margin: -16px 0px 0px -16px; - background-color: #303030; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - -ms-border-radius: 16px; - -o-border-radius: 16px; - border-radius: 16px; - -webkit-animation: scaleout 1.0s infinite ease-in-out; - animation: scaleout 1.0s infinite ease-in-out; -} -@-webkit-keyframes scaleout { - - 0% { - -webkit-transform: scale(0); - } - - - 100% { - -webkit-transform: scale(1); - opacity: 0; - } -} -@-moz-keyframes scaleout { - - 0% { - -moz-transform: scale(0); - } - - - 100% { - -moz-transform: scale(1); - opacity: 0; - } -} -@-ms-keyframes scaleout { - - 0% { - -ms-transform: scale(0); - } - - - 100% { - -ms-transform: scale(1); - opacity: 0; - } -} -@-o-keyframes scaleout { - - 0% { - -o-transform: scale(0); - } - - - 100% { - -o-transform: scale(1); - opacity: 0; - } -} -@keyframes scaleout { - - 0% { - transform: scale(0); - -webkit-transform: scale(0); - } - - - 100% { - transform: scale(1); - -webkit-transform: scale(1); - opacity: 0; - } -} - -/* pulse - end */ - -/* double pulse - start */ - -.ajax_loader .double_pulse { - width: 40px; - height: 40px; - margin: -20px 0px 0px -20px; - position: relative; -} - -.ajax_loader .double_pulse .double-bounce1, .ajax_loader .double_pulse .double-bounce2 { - width: 100%; - height: 100%; - border-radius: 50%; - background-color: #303030; - opacity: 0.6; - position: absolute; - top: 0; - left: 0; - - -webkit-animation: bounce 2.0s infinite ease-in-out; - animation: bounce 2.0s infinite ease-in-out; -} - -.ajax_loader .double_pulse .double-bounce2 { - -webkit-animation-delay: -1.0s; - animation-delay: -1.0s; -} - -@-webkit-keyframes bounce { - 0%, 100% { -webkit-transform: scale(0.0) } - 50% { -webkit-transform: scale(1.0) } -} - -@keyframes bounce { - 0%, 100% { - transform: scale(0.0); - -webkit-transform: scale(0.0); - } 50% { - transform: scale(1.0); - -webkit-transform: scale(1.0); - } -} - -/* double pulse - end */ - -/* cube - start */ - -.ajax_loader .cube { - width: 60px; - height: 60px; - margin: -30px 0px 0px -30px; - background-color: #303030; - -webkit-animation: rotateplane 1.2s infinite ease-in-out; - animation: rotateplane 1.2s infinite ease-in-out; -} - -@-webkit-keyframes rotateplane { - 0% { -webkit-transform: perspective(120px) } - 50% { -webkit-transform: perspective(120px) rotateY(180deg) } - 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) } -} - -@keyframes rotateplane { - 0% { - transform: perspective(120px) rotateX(0deg) rotateY(0deg); - -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg) - } 50% { - transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); - -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg) - } 100% { - transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - } -} - -/* cube - end */ - -/* rotating cubes - start */ - -.ajax_loader .rotating_cubes { - width: 32px; - height: 32px; - margin: -16px 0px 0px -16px; - position: relative; -} - -.ajax_loader .rotating_cubes .cube1, .ajax_loader .rotating_cubes .cube2 { - background-color: #303030; - width: 10px; - height: 10px; - position: absolute; - top: 0; - left: 0; - - -webkit-animation: cubemove 1.8s infinite ease-in-out; - animation: cubemove 1.8s infinite ease-in-out; -} - -.ajax_loader .rotating_cubes .cube2 { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} - -@-webkit-keyframes cubemove { - 25% { -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5) } - 50% { -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg) } - 75% { -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5) } - 100% { -webkit-transform: rotate(-360deg) } -} - -@keyframes cubemove { - 25% { - transform: translateX(42px) rotate(-90deg) scale(0.5); - -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); - } 50% { - transform: translateX(42px) translateY(42px) rotate(-179deg); - -webkit-transform: translateX(42px) translateY(42px) rotate(-179deg); - } 50.1% { - transform: translateX(42px) translateY(42px) rotate(-180deg); - -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); - } 75% { - transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); - -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); - } 100% { - transform: rotate(-360deg); - -webkit-transform: rotate(-360deg); - } -} - -/* rotating cubes - end */ - -/* stripes - start */ - -.ajax_loader .stripes { - width: 50px; - height: 60px; - margin: -30px 0px 0px -25px; - text-align: center; - font-size: 10px; -} - -.ajax_loader .stripes > div { - background-color: #303030; - height: 100%; - width: 6px; - display: inline-block; - margin: 0 3px 0 0; - - -webkit-animation: stretchdelay 1.2s infinite ease-in-out; - animation: stretchdelay 1.2s infinite ease-in-out; -} - -.ajax_loader .stripes .rect2 { - -webkit-animation-delay: -1.1s; - animation-delay: -1.1s; -} - -.ajax_loader .stripes .rect3 { - -webkit-animation-delay: -1.0s; - animation-delay: -1.0s; -} - -.ajax_loader .stripes .rect4 { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} - -.ajax_loader .stripes .rect5 { - -webkit-animation-delay: -0.8s; - animation-delay: -0.8s; -} - -@-webkit-keyframes stretchdelay { - 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } - 20% { -webkit-transform: scaleY(1.0) } -} - -@keyframes stretchdelay { - 0%, 40%, 100% { - transform: scaleY(0.4); - -webkit-transform: scaleY(0.4); - } 20% { - transform: scaleY(1.0); - -webkit-transform: scaleY(1.0); - } -} - -/* stripes - end */ - -/* wave - start */ - -.ajax_loader .wave { - width: 72px; - text-align: center; - margin: -9px 0px 0px -36px; -} - -.ajax_loader .wave > div { - width: 18px; - height: 18px; - background-color: #303030; - margin: 0px 3px 0px 0px; - - border-radius: 100%; - display: inline-block; - -webkit-animation: bouncedelay 1.4s infinite ease-in-out; - animation: bouncedelay 1.4s infinite ease-in-out; - /* Prevent first frame from flickering when animation starts */ - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.ajax_loader .wave .bounce1 { - -webkit-animation-delay: -0.32s; - animation-delay: -0.32s; -} - -.ajax_loader .wave .bounce2 { - -webkit-animation-delay: -0.16s; - animation-delay: -0.16s; -} - -@-webkit-keyframes bouncedelay { - 0%, 80%, 100% { -webkit-transform: scale(0.0) } - 40% { -webkit-transform: scale(1.0) } -} - -@keyframes bouncedelay { - 0%, 80%, 100% { - transform: scale(0.0); - -webkit-transform: scale(0.0); - } 40% { - transform: scale(1.0); - -webkit-transform: scale(1.0); - } -} - -/* wave - end */ - -/* two_rotating_circles - start */ - -.ajax_loader .two_rotating_circles { - width: 40px; - height: 40px; - margin: -20px 0px 0px -20px; - position: relative; - text-align: center; - - -webkit-animation: rotatecircles 2.0s infinite linear; - animation: rotatecircles 2.0s infinite linear; -} - -.ajax_loader .two_rotating_circles .dot1, .ajax_loader .two_rotating_circles .dot2 { - width: 60%; - height: 60%; - display: inline-block; - position: absolute; - top: 0; - background-color: #303030; - border-radius: 100%; - - -webkit-animation: bounce 2.0s infinite ease-in-out; - animation: bounce 2.0s infinite ease-in-out; -} - -.ajax_loader .two_rotating_circles .dot2 { - top: auto; - bottom: 0px; - -webkit-animation-delay: -1.0s; - animation-delay: -1.0s; -} - -@-webkit-keyframes rotatecircles { 100% { -webkit-transform: rotate(360deg) }} - -@keyframes rotatecircles { 100% { transform: rotate(360deg); -webkit-transform: rotate(360deg) }} - -/* two_rotating_circles - end */ - -/* five_rotating_circles - start */ - -.ajax_loader .five_rotating_circles { - width: 60px; - height: 60px; - margin: -30px 0px 0px -30px; - position: relative; -} - -.ajax_loader .five_rotating_circles .container1 > div, .ajax_loader .five_rotating_circles .container2 > div, .ajax_loader .five_rotating_circles .container3 > div { - width: 12px; - height: 12px; - background-color: #303030; - border-radius: 100%; - position: absolute; - - -webkit-animation: bouncedelay 1.2s infinite ease-in-out; - animation: bouncedelay 1.2s infinite ease-in-out; - /* Prevent first frame from flickering when animation starts */ - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.ajax_loader .five_rotating_circles .spinner-container { - position: absolute; - width: 100%; - height: 100%; -} - -.ajax_loader .five_rotating_circles .container2 { - -webkit-transform: rotateZ(45deg); - transform: rotateZ(45deg); -} - -.ajax_loader .five_rotating_circles .container3 { - -webkit-transform: rotateZ(90deg); - transform: rotateZ(90deg); -} - -.ajax_loader .five_rotating_circles .circle1 { top: 0; left: 0; } -.ajax_loader .five_rotating_circles .circle2 { top: 0; right: 0; } -.ajax_loader .five_rotating_circles .circle3 { right: 0; bottom: 0; } -.ajax_loader .five_rotating_circles .circle4 { left: 0; bottom: 0; } - -.ajax_loader .five_rotating_circles .container2 .circle1 { - -webkit-animation-delay: -1.1s; - animation-delay: -1.1s; -} - -.ajax_loader .five_rotating_circles .container3 .circle1 { - -webkit-animation-delay: -1.0s; - animation-delay: -1.0s; -} - -.ajax_loader .five_rotating_circles .container1 .circle2 { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} - -.ajax_loader .five_rotating_circles .container2 .circle2 { - -webkit-animation-delay: -0.8s; - animation-delay: -0.8s; -} - -.ajax_loader .five_rotating_circles .container3 .circle2 { - -webkit-animation-delay: -0.7s; - animation-delay: -0.7s; -} - -.ajax_loader .five_rotating_circles .container1 .circle3 { - -webkit-animation-delay: -0.6s; - animation-delay: -0.6s; -} - -.ajax_loader .five_rotating_circles .container2 .circle3 { - -webkit-animation-delay: -0.5s; - animation-delay: -0.5s; -} - -.ajax_loader .five_rotating_circles .container3 .circle3 { - -webkit-animation-delay: -0.4s; - animation-delay: -0.4s; -} - -.ajax_loader .five_rotating_circles .container1 .circle4 { - -webkit-animation-delay: -0.3s; - animation-delay: -0.3s; -} - -.ajax_loader .five_rotating_circles .container2 .circle4 { - -webkit-animation-delay: -0.2s; - animation-delay: -0.2s; -} - -.ajax_loader .five_rotating_circles .container3 .circle4 { - -webkit-animation-delay: -0.1s; - animation-delay: -0.1s; -} - -/* five_rotating_circles - end */ - -body.smooth_scroll { - overflow-y: hidden; -} - -body.boxed .wrapper_inner, -body.boxed .footer_inner{ - width: 1150px; - margin: 0 auto; -} - -/* ========================================================================== - Header styles - ========================================================================== */ -/** -* Generic header styles -*/ -header { - width: 100%; - display: inline-block; - margin: 0px 0px 0px 0px; - vertical-align: middle; - position: relative; - z-index: 110; - -webkit-backface-visibility:hidden; -} - -header .header_inner_left { - position: absolute; - left: 45px; - top: 0px; -} - -header .container_inner .header_inner_left{ - position: absolute; - left: 0px; - top: 0px; -} - -.boxed header{ - background-color: transparent !important; - border: 0px !important; -} - -.boxed .header_inner{ - width: 1150px; - margin: 0px auto; -} - -.header_inner_right{ - float: right; - position: relative; - z-index: 110; -} - -/* Header top styles - ========================================================================== */ -.header_top { - position: relative; - z-index: 111; - line-height: 33px; - height: 33px; - padding: 0; - font-size: 15px; - background-color: #fff; - -webkit-transition: all 0.2s ease 0s; - -moz-transition: all 0.2s ease 0s; - -o-transition: all 0.2s ease 0s; - transition: all 0.2s ease 0s; -} - -header.scrolled .header_top { - background-color: #fff !important; -} - -.header_top p{ - line-height: 32px; - padding: 0 15px; -} - -.header_top .left{ - float: left; -} - -.header_top .right{ - float: right; -} - -.header_top .right .inner #lang_sel { - float: left; - padding: 0 0 0 0px; -} - -.header_top .inner #lang_sel > ul { - list-style: none; -} - -.header_top .left .inner > div, -.header_top .left .inner > div:last-child { - float:left; - border-bottom: 0; - border-top: 0; -} - -.header_top .right .inner > div { - border-left: 0; - float: left; -} - -header.scrolled:not(.scroll_header_top_area) .header_top { - border-bottom: 0; -} - -/* header widgets in light and dark header styles - ========================================================================== */ -header.light:not(.sticky) .q_social_icon_holder i.simple_social, -header.light:not(.sticky) .header-widget, -header.light:not(.sticky) .header-widget.widget_nav_menu ul.menu > li > a, -header.light:not(.sticky) .header-widget p, -header.light:not(.sticky) .header-widget a, -header.light:not(.sticky) .header-widget span, -header.light.header_style_on_scroll .q_social_icon_holder i.simple_social, -header.light.header_style_on_scroll .header-widget, -header.light.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, -header.light.header_style_on_scroll .header-widget p, -header.light.header_style_on_scroll .header-widget a, -header.light.header_style_on_scroll .header-widget span{ - color:#ffffff; -} - -header.light:not(.sticky) .q_social_icon_holder i.simple_social, -header.light:not(.sticky) #lang_sel > ul > li > a, -header.light:not(.sticky) #lang_sel_click > ul > li> a, -header.light.header_style_on_scroll .q_social_icon_holder i.simple_social, -header.light.header_style_on_scroll #lang_sel > ul > li > a, -header.light.header_style_on_scroll #lang_sel_click > ul > li> a, -header.light:not(.sticky) .textwidget span, -header.light:not(.sticky) .textwidget span:hover, -header.light.header_style_on_scroll .textwidget span, -header.light.header_style_on_scroll .textwidget span:hover{ - color:#fff !important; -} - -header.dark:not(.sticky) .q_social_icon_holder i.simple_social, -header.dark:not(.sticky) .header-widget, -header.dark:not(.sticky) .header-widget.widget_nav_menu ul.menu > li > a, -header.dark:not(.sticky) .header-widget p, -header.dark:not(.sticky) .header-widget a, -header.dark:not(.sticky) .header-widget span, -header.dark.header_style_on_scroll .q_social_icon_holder i.simple_social, -header.dark.header_style_on_scroll .header-widget, -header.dark.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, -header.dark.header_style_on_scroll .header-widget p, -header.dark.header_style_on_scroll .header-widget a, -header.dark.header_style_on_scroll .header-widget span{ - color:#000; - -} -header.dark:not(.sticky) .q_social_icon_holder i.simple_social, -header.dark:not(.sticky) #lang_sel > ul > li > a, -header.dark:not(.sticky) #lang_sel_click > ul > li> a, -header.dark.header_style_on_scroll .q_social_icon_holder i.simple_social, -header.dark.header_style_on_scroll #lang_sel > ul > li > a, -header.dark.header_style_on_scroll #lang_sel_click > ul > li> a, -header.dark:not(.sticky) .textwidget span, -header.dark:not(.sticky) .textwidget span:hover, -header.dark.header_style_on_scroll .textwidget span, -header.dark.header_style_on_scroll .textwidget span:hover{ - color:#000 !important; -} - -/* Header bottom styles - ========================================================================== */ -.header_bottom { - padding: 0px 45px; - position: relative; - background-color: #fff; - -webkit-transition: all 0.2s ease 0s; - -moz-transition: all 0.2s ease 0s; - -o-transition: all 0.2s ease 0s; - transition: all 0.2s ease 0s; -} - -.boxed .header_bottom{ - padding: 0px 25px; -} - -/* Generic logo styles - ========================================================================== */ -.logo_wrapper{ - height: 100px; - float: left; -} - -.q_logo{ - position: relative; - top: 50%; - left: 0px; -} - -.q_logo a{ - position: relative; - display: block; - visibility: hidden; -} - -.q_logo img{ - display: block; - opacity:1; - position: absolute; - top: -50%; - width: auto !important; - max-width: none; - -webkit-transition: opacity 0.6s ease-in-out; - -moz-transition: opacity 0.6s ease-in-out; - -o-transition: opacity 0.6s ease-in-out; - -ms-transition: opacity 0.6s ease-in-out; -} - -/* Specific logo styles */ -.q_logo img.light, -.q_logo img.sticky, -.q_logo img.dark, -.q_logo img.popup, -.q_logo img.mobile { - opacity:0; -} - -header.scrolled:not(.header_style_on_scroll) .q_logo img.normal, -header.scrolled.dark:not(.header_style_on_scroll) .q_logo img.normal, -header.scrolled.light:not(.header_style_on_scroll) .q_logo img.normal { - opacity: 1; -} - -header.scrolled:not(.header_style_on_scroll) .q_logo img.light, -header.scrolled.light:not(.header_style_on_scroll) .q_logo img.light, -header.scrolled.dark:not(.header_style_on_scroll) .q_logo img.light, -header.scrolled:not(.header_style_on_scroll) .q_logo img.dark, -header.scrolled.light:not(.header_style_on_scroll) .q_logo img.dark, -header.scrolled.dark:not(.header_style_on_scroll) .q_logo img.dark { - opacity: 0; -} - - - -header.light .q_logo img.normal{ - opacity:0; -} - -header.light .q_logo img.light{ - opacity:1; -} - -header.light .q_logo img.dark{ - opacity:0; -} - -header.dark .q_logo img.normal{ - opacity:0; -} - -header.dark .q_logo img.light{ - opacity:0; -} - -header.dark .q_logo img.dark{ - opacity:1; -} - -/* Sticky header styles - ========================================================================== */ - -.hide_inital_sticky header.stick{ - -ms-transform: translateY(-100%); - -webkit-transform: translateY(-100%); - transform: translateY(-100%); -} - -.hide_inital_sticky header.stick.sticky{ - -ms-transform: none; - -webkit-transform: none; - transform: none; -} - -header.sticky { - -webkit-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -moz-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -o-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -ms-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - top: -120px; - left: 0; - position: fixed; - -moz-background-clip:border; - -webkit-background-clip:border; - background-clip:border-box; - -moz-background-clip:padding; - -webkit-background-clip:padding; - background-clip:padding-box; - -moz-background-clip:content; - -webkit-background-clip:content; - background-clip:content-box; -} - -header.sticky .header_top{ - display: none; -} - -header.sticky .header_bottom { - background-color: #fff !important; - box-shadow: 0 1px 3px rgba(0,0,0,0.11); -} -header.sticky.no_shadow .header_bottom { - box-shadow: none; -} -header.sticky.centered_logo { - top: -300px; -} - -header.sticky.sticky_animate { - top:0px; -} - -header.sticky:not(.header_style_on_scroll) .q_logo img.sticky { - opacity:1; -} - -header.sticky:not(.header_style_on_scroll) .q_logo img.normal, -header.sticky:not(.header_style_on_scroll) .q_logo img.light, -header.sticky:not(.header_style_on_scroll) .q_logo img.dark, -header.sticky:not(.header_style_on_scroll) .q_logo img.popup, -header.sticky:not(.header_style_on_scroll) .q_logo img.mobile{ - opacity:0 !important; -} - -header.sticky .logo_wrapper, -header.sticky.centered_logo .logo_wrapper{ - height: 60px !important; - float: left; -} - -header.sticky .drop_down .second{ - margin-top: 0; -} - -header.sticky .header_fixed_right_area { - display: none; -} - -header.sticky .side_menu_button{ - height: 60px; -} - -.sticky .header_menu_bottom{ - position: static; -} - -/* Fixed header styles - ========================================================================== */ -header.fixed, -header.fixed_hiding, -header.fixed_top_header .top_header{ - -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - width: 100%; - position: fixed; - z-index: 110; - top:0px; - left: 0px; -} - -header.fixed.scrolled .header_bottom, -header.fixed_hiding.scrolled .header_bottom{ - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.11); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.11); - box-shadow: 0 1px 3px rgba(0,0,0,0.11); - background-color: #fff; -} - -/* Header with menu on bottom styles - ========================================================================== */ -header.menu_bottom .header_inner_left { - left: 0; -} - -header:not(.sticky) .header_menu_bottom nav.main_menu > ul > li > a { - line-height: 60px; -} - -header:not(.sticky) .header_menu_bottom nav.main_menu > ul > li:first-child > a { - padding-left: 0; -} - -header.menu_bottom:not(.sticky) .drop_down .second { - top: 100%; -} - -header:not(.sticky) .header_menu_bottom .side_menu_button { - height: 60px; -} - -header.menu_bottom.has_header_fixed_right .mobile_menu_button { - height: 130px; -} - -header.menu_bottom .header_inner_left{ - position: relative; -} - -.menu_bottom.sticky .container_inner .header_inner_left{ - position: absolute; -} - -.menu_bottom .logo_wrapper{ - float: none; - -} -.menu_bottom .q_logo a{ - display:inline-block; -} -.menu_bottom.sticky .logo_wrapper{ - float: left; -} - -.header_menu_bottom { - position: relative; - display: block; -} - -/* Header styles when logo is in center - ========================================================================== */ -header.centered_logo{ - text-align: center; -} - -header.centered_logo .header_inner_left{ - float: none; - position: relative; - display: block; - margin: 20px 0px 10px 0px; -} - -header.centered_logo.sticky .header_inner_left{ - margin: 0px; -} - -header.centered_logo .logo_wrapper{ - float: none; - height: auto !important; -} - -header.centered_logo .q_logo{ - top: 0px; -} - -header.centered_logo.sticky .q_logo{ - top: 50%; -} - -header.centered_logo .q_logo a{ - display: inline-block; - vertical-align: middle; -} - -header.centered_logo .q_logo img{ - top: 0px; - margin: 0px; -} - -@media only screen and (min-width: 1000px){ - header.centered_logo:not(.sticky ) .q_logo img{ /* only not sticky is set here because on sticky menu logo is moved left from site left edge */ - -webkit-transform: translate(-50%, 0px); - -moz-transform: translate(-50%, 0px); - -ms-transform: translate(-50%, 0px); - -o-transform: translate(-50%, 0px); - transform: translate(-50%, 0px); - } -} -header.centered_logo.centered_logo_animate .q_logo img, -header:not(.centered_logo) .q_logo img{ - height: 100%; -} - -header.centered_logo.sticky .q_logo img{ - top: -50%; -} - -header.centered_logo.sticky .q_logo img{ - height: 100% !important; -} - -header.centered_logo .header_inner_right{ - float: none; - display: inline-block; - position: relative; - vertical-align: middle; -} - -header.centered_logo .header_right_widget{ - float: left; -} - -header.centered_logo nav.main_menu, -header.centered_logo nav.main_menu.right{ - position: relative; - display: inline-block; - left: auto; - float: none; - vertical-align: middle; -} - -header.centered_logo nav.main_menu > ul{ - left: 0px; -} - -@media only screen and (min-width: 1000px){ - - header.fixed_hiding .holeder_for_hidden_menu{ - overflow: hidden; - max-height: 150px; - vertical-align: middle; - -webkit-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; - -moz-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; - -o-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; - -ms-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; - transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; - } - - header.fixed_hiding.scrolled .holeder_for_hidden_menu{ - max-height: 0px; - } - - header.fixed_hiding .holeder_for_hidden_menu:hover{ - overflow: visible; - } - - header.fixed_hiding.scrolled:hover .holeder_for_hidden_menu{ - max-height: 150px; - transition-duration: 0.5s; - -webkit-transition-duration: 0.8s; - -moz-transition-duration: 0.8s; - -ms-transition-duration: 0.8s; - -o-transition-duration: 0.8s; - } - - header.fixed_hiding.centered_logo .header_inner_left{ - margin: 20px 0px; - display: table; - width: 100%; - } - - header.fixed_hiding.centered_logo.fixed_hiding .header_inner_left{ - height: 50px; - } - - header.fixed_hiding .header-left-from-logo-widget, - header.fixed_hiding .header-right-from-logo-widget, - header.fixed_hiding .logo_wrapper{ - display: table-cell; - width: 33.33%; - vertical-align: middle; - position: relative; - } - - header.fixed_hiding .header-left-from-logo-widget-inner, - header.fixed_hiding .header-right-from-logo-widget-inner{ - width: 100%; - } - - header.fixed_hiding .header-left-from-logo-widget{ - text-align: left; - } - - header.fixed_hiding .header-right-from-logo-widget{ - text-align: right; - } - - header.fixed_hiding .q_logo a, - header.fixed_hiding .q_logo{ - max-height: 124px; - opacity: 1; - -webkit-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; - -moz-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; - -o-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; - -ms-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; - transition: max-height 0.2s ease-out 0s, opacity 0.2s ease 0s; - } - - header.fixed_hiding.scrolled .q_logo, - header.fixed_hiding.scrolled .q_logo a{ - -webkit-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; - -moz-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; - -o-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; - -ms-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; - transition: max-height 0.2s ease-out 0s, opacity 0.4s ease 0s; - max-height: 0px !important; - opacity: 0; - } - - header.fixed_hiding .q_logo_hidden a{ - height: 50px; - position: relative; - display: block; - opacity: 0; - max-height: 0px; - -webkit-transition: opacity 0s ease 0s, max-height 0s ease 0s; - -moz-transition: opacity 0s ease 0s, max-height 0s ease 0s; - -o-transition: opacity 0s ease 0s, max-height 0s ease 0s; - -ms-transition: opacity 0s ease 0s, max-height 0s ease 0s; - transition: opacity 0s ease 0s, max-height 0s ease 0s; - } - - header.fixed_hiding.scrolled .q_logo_hidden a{ - max-height: 500px; - opacity: 1; - -webkit-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; - -moz-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; - -o-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; - -ms-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; - transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; - } - -} - -/* Main navigation styles - ========================================================================== */ -nav.main_menu{ - position: absolute; - left: 50%; - z-index: 100; - text-align: left; -} - -nav.main_menu.right{ - position: relative; - left: auto; - float: right; -} - -nav.main_menu ul { - list-style:none outside none; - margin:0px; - padding:0px; -} - -nav.main_menu > ul { - left: -50%; - position: relative; -} - -nav.main_menu.right > ul{ - left: auto; -} - -nav.main_menu ul li{ - display:inline-block; - float:left; - padding:0px; - margin:0px; - background-repeat: no-repeat; - background-position: right; -} - -nav.main_menu ul li a { - color: #777; - font-weight: 400; - text-decoration: none; - display: inline-block; - position: relative; - line-height: 100px; - padding: 0; - margin: 0; - cursor: pointer; -} - -nav.main_menu > ul > li > a > i.menu_icon { - margin-right: 7px; -} - -header.sticky nav.main_menu > ul > li > a, -.light.sticky nav.main_menu > ul > li > a, -.light.sticky nav.main_menu > ul > li > a:hover, -.light.sticky nav.main_menu > ul > li.active > a, -.dark.sticky nav.main_menu > ul > li > a, -.dark.sticky nav.main_menu > ul > li > a:hover, -.dark.sticky nav.main_menu > ul > li.active > a{ - line-height: 60px; -} - -nav.main_menu > ul > li > a, -nav.main_menu > ul > li > a { - display: inline-block; - height: 100%; - background-color: transparent; - -webkit-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; - -o-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; - -ms-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; -} - -.with_hover_bg_color nav.main_menu > ul > li > a { - -webkit-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; - -moz-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; - -ms-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; - -o-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; - transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; -} - -header:not(.with_hover_bg_color) nav.main_menu > ul > li:hover > a{ - opacity: 0.8; -} -nav.main_menu>ul>li.active > a { - color: #303030; -} - -nav.main_menu > ul > li > a > i.blank{ - display: none; -} - -nav.main_menu > ul > li.has_sub > a > i.q_menu_arrow { - display: inline-block; - margin-left: 6px; -} - -.light:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a, -.light:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a:hover, -.light:not(.sticky):not(.scrolled) nav.main_menu > ul > li.active > a, -.light:not(.sticky):not(.scrolled) nav.main_menu > ul > li:before, -.light:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a, -.light.header_style_on_scroll nav.main_menu > ul > li > a:hover, -.light.header_style_on_scroll nav.main_menu > ul > li.active > a, -.light.header_style_on_scroll nav.main_menu > ul > li:before{ - color: #fff; -} - -.dark:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a, -.dark:not(.sticky):not(.scrolled) nav.main_menu > ul > li.active > a, -.dark:not(.sticky):not(.scrolled) nav.main_menu > ul > li:not(:first-child):before, -.dark.header_style_on_scroll nav.main_menu > ul > li > a, -.dark.header_style_on_scroll nav.main_menu > ul > li.active > a, -.dark.header_style_on_scroll nav.main_menu > ul > li:not(:first-child):before{ - color: #000; -} - -nav.main_menu > ul > li > a { - position: relative; - padding: 0 17px; - color: #9d9d9d; - text-transform: uppercase; - font-weight: 600; - font-size: 13px; - letter-spacing: 1px; - -} - -/* DROP DOWN MENU - START */ - -.drop_down ul{ - list-style: none; -} - -.drop_down ul li{ - position: relative; -} - -header.transparent.fixed.scrolled .drop_down .second, -header.transparent.fixed_hiding.scrolled .drop_down .second{ - top: 100%; -} - -.drop_down .second { - left: 0; - margin: 0; - top: 100%; - position: absolute; - display: block; - visibility: hidden; - overflow: hidden; - opacity: 0; - z-index: 10; - /*margin-top: 1px;*/ - - -webkit-transition: top 0.3s ease-in-out; - -moz-transition: top 0.3s ease-in-out; - -ms-transition: top 0.3s ease-in-out; - -o-transition: top 0.3s ease-in-out; - transition: top 0.3s ease-in-out; -} - -header.transparent:not(.sticky) .drop_down .second { - top: 75%; -} - -header.transparent.with_border:not(.sticky) .drop_down .second, -header.transparent.with_hover_bg_color:not(.sticky) .drop_down .second { - top: 100%; -} - -.drop_down li.left_position .second{ - left: auto; - right: 0px; -} - -header.transparent .drop_down .second:not(.right) { - left: 16px; -} - -header.transparent.with_hover_bg_color .drop_down .second:not(.right) { - left: 0; -} - -.drop_down li.right_position .second { - left: -100%; - /*right: 0;*/ -} - -.drop_down .second.drop_down_start{ - visibility: visible; - overflow: visible; - opacity: 1; -} - - - -nav.main_menu > ul > li:hover > .second{ - z-index: 20; -} - -.drop_down .second .inner{ - position: relative; - padding: 0px; - display: block; - z-index: 997; -} - -.drop_down .second .inner > ul, -li.narrow .second .inner ul { - display:inline-block; - position: relative; - background-color: #262626; - border-color:#3d3d3d; -} - -li.narrow .second .inner ul { - padding: 7px 0; -} - -.drop_down .second .inner ul li { - display: block; - padding: 0 15px; - position: relative; - float: none; - height: auto; - background: 0; - width: 190px; -} - -li.narrow .second .inner ul li:last-child { - border-bottom: none; -} - -.drop_down .wide.left_position .second ul li, -.drop_down .wide.right_position .second ul li { - width: 180px; -} - -.drop_down .second .inner ul li a, -.drop_down .second .inner ul li h5 { - display: block; - font-weight: 600; - color: #9d9d9d; - height: auto; - line-height: 16px; - margin: 0; - padding: 9px 0; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; - font-size: 11px; - text-transform: uppercase; - letter-spacing: 1px; -} - -.drop_down .second .inner > ul > li:last-child > a, -.drop_down .second .inner > ul > li > ul > li:last-child > a, -.drop_down .second .inner > ul > li > ul > li > ul > li:last-child > a { - border-bottom: 0; -} - -.drop_down .second .inner ul.right li a{ - padding: 9px 20px 9px 0; -} - -.drop_down .second .inner > ul > li > a:hover, -.drop_down .second .inner ul li.sub ul li a:hover{ - color: #fff; - /*background-color: #474747;*/ -} - -.drop_down .narrow .second .inner ul li { - padding: 0; - width: 225px; -} - -.drop_down .narrow .second .inner ul li a { - padding-left: 20px; - padding-right: 20px; -} - -.drop_down .wide .second ul li a, -.drop_down .wide .second .inner ul li.sub a, -.drop_down .wide .second .inner ul li h5 { - background: 0; -} - -.drop_down .second i { - display: none; -} - -.drop_down .second .inner ul li ul{ - position: absolute; - left: 100%; - top: -7px; - height: auto; - display: none; - overflow: hidden; - z-index: 10; -} - -.drop_down .second .inner ul li:hover ul{ - z-index: 20; - display: block; -} - -.drop_down .second.right { - right: 0px; - left: auto; -} - -.drop_down .second .inner ul.right li a, -.drop_down .second .inner ul.right li h5{ - text-align: right; -} - -.drop_down .second .inner ul.right li ul{ - left: -100%; -} - -.drop_down .second .inner ul li.sub ul li a, -.drop_down .second .inner ul.right li.sub ul li a{ - background: none; -} - -.drop_down .second .inner .widget{ - padding: 0px 20px; -} - -.drop_down .second .inner .widget p{ - font-size: 13px; - line-height: 16px; - padding: 12px 0px; -} - -/* DROP DOWN MENU - END */ - -/* DROP DOWN MENU WIDE - START */ - -.drop_down .wide .second ul{ - padding: 15px 10px; -} -.drop_down .second ul li{ - border-bottom-width: 1px; - border-bottom-color: #3d3d3d; -} -.drop_down .wide .second ul li{ - float: left; - width: 249px; - padding: 0 10px 0 10px; - border-left: 1px solid #3d3d3d; - border-bottom: 0; -} - -.drop_down .wide .second > .inner > ul > li.sub > ul > li > a, -.drop_down .wide .second ul li a { - padding: 11px 9px; -} - -.drop_down .wide:not(.right_position) .second ul li:first-child, -.drop_down .wide.right_position .second ul li:last-child { - border-left-color: transparent; -} - -.drop_down .wide .second ul li:last-child { - margin-right: 0; -} - -.drop_down .wide.right_position .second ul li{ - float: right; - } - -.drop_down .wide .second ul li:hover{ - background-color: transparent; -} - -.drop_down .wide .second ul li:nth-child(4n+1){ - clear: both; -} - -.drop_down .second .inner ul li.sub a i.q_menu_arrow{ - display: inline-block; - float: right; - position: relative; - top: 2px; - font-size: 12px; - color: #888; -} - -.drop_down .second .inner ul li.sub ul li a i.q_menu_arrow, -.drop_down .wide .second .inner ul li.sub a i.q_menu_arrow { - display: none; -} - -.drop_down .second .inner ul.right li.sub a i.q_menu_arrow{ - float: left; - -ms-transform: rotate(180deg); - -moz-transform: rotate(180deg); - -webkit-transform: rotate(180deg); -} - -.drop_down .wide .second .inner > ul > li > a{ - color: #fff; - border-bottom: 0; - text-transform: uppercase; - letter-spacing: 1px; - font-weight: 600; -} - -.drop_down .wide .second .inner > ul > li > a{ - margin-bottom: 7px; - font-size: 13px; -} - -.drop_down .wide .second .inner ul li.sub h5 a, -.drop_down .wide .second .inner ul li h5 a{ - padding: 0px !important; -} - -.drop_down .wide .second ul li ul{ - display: block; - left: 0; - padding: 0; - position: relative; - top: 0; - visibility: visible; - background-color: transparent !important; -} - -.drop_down .wide .second ul li ul .widget{ - padding:0 10px; -} - -/* Wide drop down with full width background styles - ========================================================================== */ -.drop_down .wide.wide_background .second{ - background-color: #262626; -} - -.drop_down .wide.wide_background .second .inner{ - text-align:center; -} - -.drop_down .wide.wide_background .second .inner ul{ - text-align:left; -} -.drop_down .wide.wide_background .second .inner { - text-align: center; -} - -/* custom widget area in popup - start */ -.drop_down .second .inner ul li ul{ - overflow: visible; -} - -.drop_down .wide .second ul li.show_widget_area_in_popup:hover .popup_wrapper > a{ - color: #fff; /* this is added to style dynamic css also! */ -} - -.drop_down .wide .second ul li.show_widget_area_in_popup .popup_wrapper{ - position: relative; - display: inline-block; - vertical-align: middle; -} - - -.drop_down .wide .second ul li.show_widget_area_in_popup a{ - display: inline-block; - vertical-align: middle; -} - -.drop_down .wide .second ul li.show_widget_area_in_popup .widget{ - height: 0px; - width: 0px; - overflow: hidden; - opacity: 0; - position: absolute; - left: 100%; - top: 0px; - padding: 5px; - margin: 5px 0px 0px 5px; - background-color: #262626; -} - -.drop_down .wide .second ul li ul li{ - z-index: 1; -} - -.drop_down .wide .second ul li.show_widget_area_in_popup:hover{ - z-index: 10; -} - -.drop_down .wide .second ul li.show_widget_area_in_popup:hover .widget{ - height: auto; - width: auto; - opacity: 1; -} - -.drop_down .wide .second ul li.show_widget_area_in_popup .widget img{ - max-width: inherit; - display: block; - position: relative; -} - -.drop_down .wide .second ul li.show_widget_area_in_popup .widget a{ - padding: 0px; -} - -/* custom widget area in popup - end */ - -.drop_down .wide .second ul li ul li{ - padding: 0; - margin: 0; - border: 0; -} - -.drop_down .wide .second ul li ul li.menu-item-has-children > a, -.drop_down .wide .second ul li ul li.menu-item-has-children > a:hover{ - border-bottom: 0 none; - color: #303030; - font-size: 15px; -} - -/* DROP DOWN MENU WIDE - END */ - - -/* DROP DOWN MENU WIDE ICONS - START */ - -.drop_down .wide.icons .second ul li a span{ - position: relative; - display: block; -} - -.drop_down .wide.icons .second i{ - width: 24px; - height: 16px; - float: left; - display: inline-block; - color: #888; - line-height: 16px; - - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - -.drop_down .wide.icons .second a:hover i{ - color: #fff; -} - -.drop_down .wide.icons .second i.blank{ - background: none; - border: 0px; - display:none; -} - -/* DROP DOWN MENU WIDE ICONS - END */ - -/* Sticky with left and right menu - start */ - -@media only screen and (min-width: 1000px){ - - header.stick_with_left_right_menu:not(.sticky){ - text-align: center; - } - - .hide_inital_sticky header.stick_with_left_right_menu{ - -ms-transform: translateY(-100%); - -webkit-transform: translateY(-100%); - transform: translateY(-100%); - } - - .hide_inital_sticky header.stick_with_left_right_menu.sticky{ - -ms-transform: none; - -webkit-transform: none; - transform: none; - } - - header.stick_with_left_right_menu .header_inner_left{ - display: inline-block; - vertical-align: middle; - position: relative; - top: 0px; - left: auto; - z-index: 100; - } - - header.stick_with_left_right_menu.sticky .header_inner_left{ - display: none; - } - - header.stick_with_left_right_menu nav.main_menu.left_side{ - text-align: right; - position: absolute; - width: 49%; - top: 0px; - left: 0px; - z-index: 50; - } - - header.stick_with_left_right_menu nav.main_menu.left_side > ul{ - text-align: left; - display: inline-block; - vertical-align: middle; - } - - header.stick_with_left_right_menu nav.main_menu.right_side{ - position: absolute; - width: 49%; - top: 0px; - right: 0px; - left: auto; - z-index: 50; - } - - header.stick_with_left_right_menu nav.main_menu.left_side:hover, - header.stick_with_left_right_menu nav.main_menu.right_side:hover{ - z-index: 200; - } - - header.stick_with_left_right_menu.sticky nav.main_menu.left_side, - header.stick_with_left_right_menu.sticky nav.main_menu.right_side{ - position: relative; - display: inline-block; - vertical-align: middle; - } - - - header.stick_with_left_right_menu.sticky nav.main_menu.left_side > ul > li:last-child, - header.stick_with_left_right_menu.sticky nav.main_menu.right_side > ul > li:first-child{ - margin: 0px !important; - } - - - nav.main_menu.left_side > ul, - nav.main_menu.right_side > ul{ - left: auto; - } - -} - -/* Sticky with left and right menu - end */ - - -/* Fixed Minimal header type styles -========================================================================== */ - -.fixed_minimal .container_inner .header_inner_left, -.fixed_minimal .header_inner_left{ - position:relative; - left:auto; - top:auto; - float:left; -} - -.fixed_minimal .container_inner .logo_wrapper, -.fixed_minimal .logo_wrapper{ - float:none; - position:absolute; - left:50%; - top:0; -} -@media only screen and (min-width: 1000px){ - .fixed_minimal .q_logo a img{ - -webkit-transform: translate(-50%, 0px); - -moz-transform: translate(-50%, 0px); - -ms-transform: translate(-50%, 0px); - -o-transform: translate(-50%, 0px); - transform: translate(-50%, 0px); - } -} - - -.fixed_minimal .popup_menu .line:after, -.fixed_minimal .popup_menu .line:before{ - z-index:1; -} - - -.fixed_minimal .side_menu_button > a{ - margin:0; -} - - - -/* Fixed Minimal header type styles end -========================================================================== */ - -/* Fixed Top Header header type styles - ========================================================================== */ - -.fixed_top_header .top_header{ - background-color: #fff; - position:fixed; - z-index:110; - width:100%; - left:0; - top:0; - -webkit-backface-visibility: hidden; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.fixed_top_header .top_header .left{ - float:left; -} - -.fixed_top_header .top_header .right{ - float:right; -} - -.fixed_top_header .top_header nav.main_menu{ - position:relative; - left:0; -} - -.fixed_top_header .top_header nav.main_menu > ul{ - left:0; -} - -.fixed_top_header .header_inner_center{ - text-align:center; -} - -.fixed_top_header .logo_wrapper{ - float:none; - padding:25px 0 25px 0; -} - -.fixed_top_header .q_logo{ - top:0; -} - -.fixed_top_header .q_logo a{ - display:inline-block; - vertical-align:middle; -} - -.fixed_top_header .q_logo a img{ - top: 0; - left:0; - -webkit-transform: translate(-50%, 0px); - -moz-transform: translate(-50%, 0px); - -ms-transform: translate(-50%, 0px); - -o-transform: translate(-50%, 0px); - transform: translate(-50%, 0px); -} - -.fixed_top_header .side_menu_button, -.fixed_top_header .shopping_cart_inner, -.fixed_top_header .header_bottom_right_widget_holder{ - height:45px; -} - -.fixed_top_header nav.main_menu > ul > li > a{ - line-height:45px; -} - -.fixed_top_header.has_top .bottom_header{ - padding-top: 45px; -} - -.fixed_top_header .bottom_header{ - background-color: #fff; -} - -.fixed_top_header .header_bottom_center_widget{ - padding-bottom:20px; -} - -.fixed_top_header .top_header .header-widget{ - float:left; -} - - -.fixed_top_header nav.mobile_menu{ - background-color: #fff; -} - -.fixed_top_header .qode_search_form_3 .qode_search_close{ - font-size:25px; -} - -.fixed_top_header .qode_search_form_3{ - position:fixed; - left:0; - top:0; -} - -.fixed_top_header .top_header > .left{ - padding-left:45px; -} -.fixed_top_header .top_header > .right{ - padding-right:45px; -} - -.fixed_top_header .top_header .container_inner .left, -.fixed_top_header .top_header .container_inner .right{ - padding-left:0; - padding-right:0; -} - -.fixed_top_header.light .header_bottom_center_widget{ - color: #fff; -} - -.fixed_top_header.dark .header_bottom_center_widget{ - color: #000; -} - -header.fixed_top_header .top_header nav.main_menu > ul > li:first-child > a { - padding-left: 0; -} - - /* Fixed Top Header header type styles end - ========================================================================== */ - -.mobile_menu_button{ - display: none; - float: left; - height: 100px; - margin: 0 20px 0 0; -} - - - -.mobile_menu_button span { - color: #777; - width: 19px; - height: 17px; - font-size: 14px; - z-index: 50; - display: table-cell; - position: relative; - cursor: pointer; - vertical-align: middle; -} - -.dark .mobile_menu_button span{ - color: #000; -} - -nav.mobile_menu{ - display: none; - width: 100%; - float: left; - position: relative; - top: 0px; - text-align: left; - overflow: hidden; - background-color: #fff; - z-index: 100; -} - -nav.mobile_menu ul{ - display: none; - width: 100%; - position: relative; - list-style: none; - padding: 0; - margin: 0; -} - -nav.mobile_menu > ul{ - margin-bottom: -1px !important; -} - -nav.mobile_menu ul li{ - margin: 0px; - padding: 0px; - position: relative; -} - -nav.mobile_menu ul li a{ - -webkit-transition: all 0.2s ease; - -moz-transition: all 0.2s ease; - -o-transition: all 0.2s ease; - -webkit-tap-highlight-color: transparent; -} - -nav.mobile_menu ul li, -nav.mobile_menu ul li, -nav.mobile_menu ul li ul li { - border-bottom: 1px solid #eaeaea; -} - -nav.mobile_menu ul li.open_sub > ul { - border-top: 1px solid #eaeaea; -} - -nav.mobile_menu ul li:last-child{ - border: 0px !important; -} - -nav.mobile_menu ul > li.has_sub > span.mobile_arrow, -nav.mobile_menu ul > li.has_sub > span.mobile_arrow { - cursor: pointer; - display: inline-block; - float: right; - height: 46px; - line-height: 46px; - margin: 0px; - padding: 0px 10px 0px 0px; - position: absolute; - top: 0px; - right: 0px; - text-align: right; - width: 50px; - z-index: 9000; - -webkit-tap-highlight-color: transparent; -} - -nav.mobile_menu ul li span.mobile_arrow i, -nav.mobile_menu ul li span.mobile_arrow i{ - color: #888; -} - -nav.mobile_menu ul > li > span.mobile_arrow i{ - display:none; -} - -nav.mobile_menu ul > li.has_sub > span.mobile_arrow i{ - display:inline; -} - -nav.mobile_menu ul > li.has_sub > span.mobile_arrow i.fa-angle-down, -nav.mobile_menu ul > li.has_sub > span.mobile_arrow i.fa-angle-down{ - display:none; -} - -nav.mobile_menu ul > li.has_sub.open_sub > span.mobile_arrow i.fa-angle-right, -nav.mobile_menu ul > li.has_sub > ul.open_sub > li > span.mobile_arrow i.fa-angle-right{ - display:none; -} - -nav.mobile_menu ul > li.has_sub.open_sub > span.mobile_arrow i.fa-angle-down, -nav.mobile_menu ul > li.has_sub ul.open_sub > li > span.mobile_arrow i.fa-angle-down{ - display:inline; -} - -nav.mobile_menu ul li a, -nav.mobile_menu ul li h3{ - font-size: 13px; - font-weight: 400; - color: #888; - padding: 10px 0px 10px 0; - display: block; - position: relative; - text-transform: none; - line-height: 26px; - letter-spacing: 0; -} - -nav.mobile_menu ul li a:hover, -nav.mobile_menu ul li.active > a{ - color: #1abc9c; -} - -nav.mobile_menu ul li ul li{ - margin: 0px 0px 0px 20px; -} - - - -header:not(.centered_logo) .header_fixed_right_area { - position: absolute; - right: 0; - top: 0; - height: 100%; - line-height:100px; -} - - - -.header_menu_bottom .main_menu{ - left: auto; -} - -.sticky .header_menu_bottom .main_menu{ - float: right; - left: auto; - position: relative; -} - -.sticky .header_menu_bottom .main_menu_header_inner_right_holder .main_menu{ - float:left; -} - -.sticky .header_menu_bottom .main_menu_header_inner_right_holder.with_center_logo .main_menu{ - float:left; -} - -.sticky .header_menu_bottom .main_menu_header_inner_right_holder{ - float:right; -} - -.header_menu_bottom nav.main_menu > ul{ - left: auto; -} - -.sticky .header_menu_bottom nav.main_menu > ul{ - left: auto; -} - -.side_menu_button_wrapper{ - display: table; -} - -.side_menu_button{ - cursor: pointer; - display: table-cell; - vertical-align: middle; - height: 100px; -} -.header_bottom_right_widget_holder{ - display: table-cell; - vertical-align: middle; - height: 100%; - padding:0 17px; -} -@media only screen and (min-width: 1000px){ - - header.dark:not(.sticky):not(.scrolled) .header_bottom_right_widget_holder a.qbutton, - header.dark.header_style_on_scroll .header_bottom_right_widget_holder a.qbutton{ - border-color:#000 !important; - background-color: transparent !important; - color:#000 !important; - } - - header.light:not(.sticky):not(.scrolled) .header_bottom_right_widget_holder a.qbutton, - header.light.header_style_on_scroll .header_bottom_right_widget_holder a.qbutton{ - border-color:#fff !important; - background-color: transparent !important; - color:#fff !important; - } -} -/*header.has_woocommerce_dropdown .side_menu_button > a { - top: -8px; -}*/ - -.side_menu_button > a { - font-size: 14px; - position: relative; - display: inline; - width: 20px; - height: 20px; - padding:0 12px; -} - -.side_menu_button > a.side_menu_button_link.medium { - display: inline-block; - font-size: 21px; - line-height: 30px; - height: 30px; - width: 19px; -} - -.side_menu_button > a.side_menu_button_link.large { - display: inline-block; - font-size: 28px; - line-height: 34px; - height: 34px; - width: 24px; -} - -.side_menu_button > a, -.mobile_menu_button span { - -webkit-transition: opacity 0.3s ease; - -moz-transition: opacity 0.3s ease; - -ms-transition: opacity 0.3s ease; - -o-transition: opacity 0.3s ease; - color: #9d9d9d; -} - -.side_menu_button > a:hover, -.mobile_menu_button span:hover { - opacity: 0.8; -} - -.light:not(.sticky):not(.scrolled) .header-widget .q_social_icon_holder i.simple_social, -.light:not(.sticky):not(.scrolled) .header-widget, -.light:not(.sticky):not(.scrolled) .header-widget.widget_nav_menu ul.menu > li > a, -.light:not(.sticky):not(.scrolled) .header-widget p, -.light:not(.sticky):not(.scrolled) .header-widget a, -.light:not(.sticky):not(.scrolled) .header-widget span, -.light.header_style_on_scroll .header-widget .q_social_icon_holder i.simple_social, -.light.header_style_on_scroll .header-widget, -.light.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, -.light.header_style_on_scroll .header-widget p, -.light.header_style_on_scroll .header-widget a, -.light.header_style_on_scroll .header-widget span{ - color:#fff; - -} - -.light:not(.sticky):not(.scrolled) .header-widget .q_social_icon_holder i.simple_social, -.light:not(.sticky):not(.scrolled) .header-widget #lang_sel > ul > li > a, -.light:not(.sticky):not(.scrolled) .header-widget #lang_sel_click > ul > li> a, -.light.header_style_on_scroll .header-widget .q_social_icon_holder i.simple_social, -.light.header_style_on_scroll .header-widget #lang_sel > ul > li > a, -.light.header_style_on_scroll .header-widget #lang_sel_click > ul > li> a{ - color:#fff !important; -} - -.dark:not(.sticky):not(.scrolled) .q_social_icon_holder i.simple_social, -.dark:not(.sticky):not(.scrolled) .header-widget, -.dark:not(.sticky):not(.scrolled) .header-widget.widget_nav_menu ul.menu > li > a, -.dark:not(.sticky):not(.scrolled) .header-widget p, -.dark:not(.sticky):not(.scrolled) .header-widget a, -.dark:not(.sticky):not(.scrolled) .header-widget span, -.dark.header_style_on_scroll .q_social_icon_holder i.simple_social, -.dark.header_style_on_scroll .header-widget, -.dark.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, -.dark.header_style_on_scroll .header-widget p, -.dark.header_style_on_scroll .header-widget a, -.dark.header_style_on_scroll .header-widget span{ - color:#000; - -} - -.dark:not(.sticky):not(.scrolled) .header-widget .q_social_icon_holder i.simple_social, -.dark:not(.sticky):not(.scrolled) .header-widget #lang_sel > ul > li > a, -.dark:not(.sticky):not(.scrolled) .header-widget #lang_sel_click > ul > li> a, -.dark.header_style_on_scroll .header-widget .q_social_icon_holder i.simple_social, -.dark.header_style_on_scroll .header-widget #lang_sel > ul > li > a, -.dark.header_style_on_scroll .header-widget #lang_sel_click > ul > li> a{ - color:#000 !important; -} - -.side_menu_button a:last-child{ - padding: 0px 0px 0px 8px; -} - -.header_inner_right.left_side .side_menu_button a:last-child{ - padding: 0px; -} - -header.sticky .header_inner_right.left_side{ - display:none; -} - -.side_menu .q_font_awsome_icon .qode_icon_element -{ - color:#818181; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; - margin:0 8px 0 0; - -webkit-backface-visibility: visible; /* fix the problem with boxed background on Chrome */ -} -.side_menu li:hover .q_font_awsome_icon .qode_icon_element{ - color:#fff; -} -.q_slider { - width: 100%; - overflow: hidden; - position: relative; - z-index: 10; -} - -.ls-wp-fullwidth-helper { - left: 0px !important; -} - -/*.content{ - margin-top: 0; - position: relative; - z-index: 100; - background-color: #f6f6f6; -} - -.content.content_top_margin{ - margin-top: 100px !important; -} -.content.content_top_margin_none{ - margin-top: 0 !important; -}*/ - -.container{ - position: relative; - padding: 0; - width: 100%; - z-index:100; -} - -.container_inner{ - width: 1100px; - margin: 0px auto; -} -/*.content .container { - background-color: #f6f6f6; -} -.content .container .container_inner{ - padding:0px 0px 0px 0px; -} -.content .container .container_inner.page_container_inner{ - padding:30px 0px 0px 0px; -}*/ -.full_page_container_inner{ - padding:30px 0px 0px 0px; -} -.full_width{ - position: relative; - z-index: 100; - background-color: #f6f6f6; -} - -.header_bottom .container_inner{ - position: relative; -} - -/*.content .title .container_inner{ - padding: 0px !important; -}*/ - -section.section{ - display: block; - position: relative; - padding: 50px 0; - overflow: hidden; -} -div.section{ - position:relative; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - -} -.use_row_as_box{ - -moz-border-radius:4px; - -webkit-border-radius:4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius:4px; -} -.vc_row.disable_negative_margin { - margin-left: 0; - margin-right: 0; -} -div.video_section{ - overflow: hidden; -} - -.boxed .section .section_inner, -.grid_section .section_inner{ - width: 1100px; - margin: 0px auto; - position: relative; - z-index: 20; -} - -.full_section_inner{ - position: relative; - z-index: 20; -} -/* Section Video Background - Start */ - -.section .mobile-video-image { - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - display: none; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; - z-index: 10; -} - -.section .video-overlay { - height: 3000px; - left: 0; - opacity: 0; - position: absolute; - top: 0; - width: 100%; - z-index: 11; -} - -.section .video-overlay.active { - background-image: url("img/pixel-video.png"); - background-position: 0px 0px; - background-repeat: repeat; - opacity: 1; -} - -.section .video-wrap { - top: 0px; - left: 0px; - overflow: hidden; - position: absolute; - width: 100%; - z-index: 10; -} - -.section .video-wrap .mejs-poster { - background-size: cover!important; - -moz-background-size: cover!important; - -webkit-background-size: cover!important; - -o-background-size: cover!important; -} - -.section .video-wrap .mejs-container .mejs-controls { - display: none!important; -} - -.section .video-wrap .mejs-controls .mejs-button button:focus { - outline: none!important; -} - -.section .video-wrap .mejs-controls .mejs-time-rail .mejs-time-loaded { - background-color: rgba(255, 255, 255, 0.18) !important; -} - -.section .video-wrap .mejs-container { - background-color: transparent!important; - background-image: none!important; - height: auto !important; -} - -.section .video-wrap .mejs-mediaelement{ - background: none !important; - border: 0px !important; -} - -.section .video-wrap .mejs-container .mejs-poster img { - max-width: none!important; - width: 100%!important; -} - -.section .video-wrap .mejs-controls button { opacity: 0.8; } -.section .video-wrap .mejs-controls button:hover, .mejs-controls .mejs-fullscreen-button:hover button { opacity: 1!important;} - -.section .video-wrap .mejs-controls .mejs-time-rail .mejs-time-total { - background: #1f1f1f none repeat scroll 0 0 !important; -} - -.section .video-wrap .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current { - background: transparent!important; -} - -/* Section Video Background - End */ - -.two_columns_66_33{ - width: 100%; -} - -.two_columns_66_33>.column1{ - width: 66.66%; - float: left; -} - -.two_columns_66_33>.column1>.column_inner{ - padding: 0 20px 0 0; -} - -.two_columns_66_33>.column2{ - width: 33.33%; - float: left; -} - -.two_columns_66_33>.column2>.column_inner{ - padding: 0 0 0 20px; - -} - -.two_columns_33_66{ - width: 100%; -} - -.two_columns_33_66>.column1{ - width: 33.33%; - float: left; -} - -.two_columns_33_66>.column1>.column_inner{ - padding: 0 20px 0 0; -} - -.two_columns_33_66>.column2{ - width: 66.66%; - float: left; -} - -.two_columns_33_66>.column2>.column_inner{ - padding: 0 0 0 20px; -} - -.two_columns_75_25{ - width: 100%; -} - -.two_columns_75_25>.column1{ - width: 75%; - float: left; -} - -.two_columns_75_25>.column1>.column_inner{ - padding: 0 20px 0 0; -} - -.two_columns_75_25>.column2{ - width: 25%; - float: left; -} - -.two_columns_75_25>.column2>.column_inner{ - padding: 0 0 0 20px; -} - -.two_columns_25_75 { - width: 100%; -} - -.two_columns_25_75>.column1{ - width: 25%; - float: left; -} - -.two_columns_25_75>.column1>.column_inner{ - padding: 0 20px 0 0; -} - -.two_columns_25_75>.column2{ - width: 75%; - float: left; -} - -.two_columns_25_75>.column2>.column_inner{ - padding: 0 0 0 20px; -} - -.two_columns_50_50 { - width: 100%; -} - -.two_columns_50_50>.column1{ - width: 50%; - float: left; -} - -.two_columns_50_50>.column1>.column_inner{ - padding: 0 10px 0 0; -} - -.two_columns_50_50>.column2{ - width: 50%; - float: left; -} - -.two_columns_50_50>.column2>.column_inner{ - padding: 0 0 0 10px; -} - -.three_columns { - width: 100%; -} - -.three_columns>.column1, -.three_columns>.column2, -.three_columns>.column3{ - width: 33.33%; - float: left; -} - -.three_columns>.column1>.column_inner{ - padding: 0 15px 0 0; -} - -.three_columns>.column2>.column_inner{ - padding: 0 5px 0 10px; -} - -.three_columns>.column3>.column_inner{ - padding: 0 0 0 15px; -} - -.four_columns{ - width: 100%; -} - -.four_columns>.column1, -.four_columns>.column2, -.four_columns>.column3, -.four_columns>.column4{ - width: 25%; - float: left; -} - -.four_columns>.column1>.column_inner{ - padding: 0 15px 0 0; -} - -.four_columns>.column2>.column_inner{ - padding: 0 10px 0 5px; -} - -.four_columns>.column3>.column_inner{ - padding: 0 5px 0 10px; -} - -.four_columns>.column4>.column_inner{ - padding: 0 0 0 15px; -} - -.five_columns>.column1, -.five_columns>.column2, -.five_columns>.column3, -.five_columns>.column4, -.five_columns>.column5{ - width: 20%; - float: left; -} - -.five_columns>.column1>.column_inner, -.five_columns>.column2>.column_inner, -.five_columns>.column3>.column_inner, -.five_columns>.column4>.column_inner{ - margin: 0 2.5% 0 0; -} - -.five_columns>.column5>.column_inner{ - margin: 0; -} - -.title_outer.animate_title_area{ - overflow: hidden; -} - -/*.title{ - display: block; - width: 100%; - height: 100px; - text-align: left; - position: relative; - z-index: 101; - border-bottom-color:#eee; -}*/ - -.title_outer.with_image .title{ - height: auto !important; - line-height: normal; - background: none; -} - -.title img{ - display: block; - position: relative; - width: 100%; -} - -.title .not_responsive{ - display: none; -} - -.title .title_holder{ - display: table; - height: 100%; - left: 0; - position: relative; - width: 100%; -} - -.title_outer.with_image .title .title_holder, -.title_outer .has_fixed_background.title .title_holder, -.title_outer .has_background.title .title_holder { - position: absolute; - top: 0%; - display:block; -} - -.title .title_overlay{ - position: absolute; - width: 100%; - height: 100%; - background-repeat: repeat; - background-position: 0px 0px; - top: 0; -} - -.title .title_holder .container{ - display: table-cell; - vertical-align: middle; - background-color: transparent; -} -.title_outer.with_image .title .title_holder .container, -.title_outer .has_fixed_background.title .title_holder .container, -.title_outer .has_background.title .title_holder .container -{ - display:block; - height: 100%; -} -.content .title_outer.with_image .title .container_inner, -.title_outer .has_fixed_background.title .title_holder .container_inner, -.title_outer .has_background.title .title_holder .container_inner -{ - display: table; - height: 100%; -} -.title_subtitle_holder{ - display: block; - padding: 0px; - position:relative; -} -.title_outer.with_image .title .title_subtitle_holder, -.title_outer .has_fixed_background.title .title_subtitle_holder, -.title_outer .has_background.title .title_subtitle_holder -{ - display: table-cell; - vertical-align: middle; - width: 100%; -} -.title_subtitle_holder_inner { - position: relative; -} -.title h1{ - color: #303030; - padding: 0px; - text-transform:uppercase; - letter-spacing:1px; - font-weight: 600; - -} -.title.title_size_medium h1{ - font-size: 24px; - line-height: 1.384615384615385em; -} - -.title.title_size_small h1, -.title h1 -{ - font-size: 17px; - line-height: 1.304347826086957em; -} - -.title.title_size_large h1{ - font-size: 47px; - line-height: 60px; -} -.title_text_shadow .title h1{ - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); -} - -.subtitle{ - display:block; -} - -.title_text_shadow .subtitle{ - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); -} - -.animate_title_text .title h1{ - -webkit-animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; - -moz-animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; - -o-animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; - animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; - -webkit-animation-fill-mode: both; - -moz-animation-fill-mode: both; - -ms-animation-fill-mode: both; - -o-animation-fill-mode: both; - animation-fill-mode: both; - visibility: visible; - } - -@-webkit-keyframes title-from-right { - 0% { - filter: alpha(opacity=0); - opacity: 0; - -webkit-transform: translate(50%, 0); - } - 100% { - filter: alpha(opacity=100); - opacity: 1; - -webkit-transform: translate(0, 0); - } -} -@-moz-keyframes title-from-right { - 0% { - filter: alpha(opacity=0); - opacity: 0; - -moz-transform: translate(50%, 0); - } - 100% { - filter: alpha(opacity=100); - opacity: 1; - -moz-transform: translate(0, 0); - } -} -@-o-keyframes title-from-right { - 0% { - filter: alpha(opacity=0); - opacity: 0; - -o-transform: translate(50%, 0); - } - 100% { - filter: alpha(opacity=100); - opacity: 1; - -o-transform: translate(0, 0); - } -} -@keyframes title-from-right { - 0% { - filter: alpha(opacity=0); - opacity: 0; - transform: translate(50%, 0); - } - 100% { - filter: alpha(opacity=100); - opacity: 1; - transform: translate(0, 0); - } -} -.position_center.title .title_subtitle_holder{ - text-align:center; -} -.position_right.title .title_subtitle_holder{ - text-align:right; -} - -.position_right .breadcrumb{ - left:0; - right: auto; -} - -.title.has_background { - background-repeat: no-repeat; - background-position: center 0; -} - -.title.has_fixed_background { - background-repeat: no-repeat; - background-attachment: fixed; - background-position: center 0; - position: relative; - z-index: 101; -} -.breadcrumb{ - position:absolute; - height:100%; - font-size:13px; - top:0; - right:0; - color:#303030; -} -.breadcrumbs{ - display:table; - height:100%; - width:100%; - line-height: 1em; -} - -.breadcrumbs .breadcrumbs_inner{ - display:table-cell; - vertical-align:middle; -} - -.title_text_shadow .breadcrumbs .breadcrumbs_inner{ - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); -} - -.position_center.title .breadcrumb{ - position:relative; - text-align:center; -} -.title .separator.small, -.title .separator.small.left, -.title .separator.small.right -{ - margin-top: 14px; - margin-bottom: 10px; -} - -.title_border_in_grid_holder{ - height: 1px; - width: 1100px; - margin: 0 auto; - background-color: #eee; -} - -.breadcrumb .current{ - color:#303030; -} - -.breadcrumb a{ - color:#303030; -} - -.breadcrumb a:hover{ - color:#1abc9c; -} - -.touch .title.has_fixed_background { - background-attachment: scroll; -} - -.box_image_with_border{ - display: block; - position: relative; - border-bottom: 5px solid #dddddd; - -webkit-transition: all .4s ease-out 0s; - -moz-transition: all .4s ease-out 0s; - -o-transition: all .4s ease-out 0s; - -ms-transition: all .4s ease-out 0s; - text-align: center; -} - -.box_image_with_border:hover{ - border-color: #1abc9c; -} - -.box_image_with_border h3{ - margin: 0 0 15px; -} - -.box_image_holder{ - display: block; - position: relative; - margin: 0 0 56px; - text-align: left; -} - -.box_image_holder a{ - position: relative; - display: block; -} - -.box_image_holder .box_image_shadow{ - display: block; - position: absolute; - bottom: -8px; - left: 0; - width: 100%; - height: 100%; - background-image: url('img/box_image_shadow.png'); - background-repeat: no-repeat; - background-position: center bottom; - background-size: 100% 30px; - -webkit-background-size: 100% 30px; - -moz-background-size: 100% 30px; - -o-background-size: 100% 30px; - -webkit-transition: all .4s ease-out 0s; - -moz-transition: all .4s ease-out 0s; - -o-transition: all .4s ease-out 0s; - -ms-transition: all .4s ease-out 0s; -} - -.box_image_with_border:hover .box_image_shadow{ - bottom: -13px; - opacity: 0.2; - filter: alpha(opacity=20); -} - -.box_image_holder .image_holder_inner{ - position: relative; - display: inline-block; - width: 100%; - top: 0px; - left: 0px; - -webkit-transition: all .4s ease-out 0s; - -moz-transition: all .4s ease-out 0s; - -o-transition: all .4s ease-out 0s; - -ms-transition: all .4s ease-out 0s; -} - -.box_image_with_border:hover .box_image_holder .image_holder_inner{ - top: -15px; -} - -.box_image_holder img{ - width: 100%; -} - -.box_image_holder .box_icon{ - display: inline-block; - position: absolute; - left: 50%; - bottom: 0px; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); -} - -.box_image_holder .box_icon .fa-stack{ - margin: 0 0 0 -50%; - font-size: 4em; -} - -.box_image_holder .box_icon .fa-stack i{ - margin: 35% 0 0; -} - -.box_image_holder .box_icon .fa-stack i.fa-stack-base { - color: #1abc9c; -} - -.separator { - position: relative; - display: block; - height: 1px; - background-color: #eaeaea; - margin: 10px 0; -} - -.separator.transparent { - background-color: transparent; -} - -.separator.small { - background-color: #303030; - height: 2px; - position: relative; - width: 22px; - display: block; - margin: 10px auto 20px auto; -} - -.wpb_column > .wpb_wrapper .separator.small { - margin-bottom: 20px; -} - -.separator.small.left { - margin: 10px 0 20px 0; -} - -.separator.small.right { - margin: 10px 0 20px auto; -} - -/* ========================================================================== - Icon list shortcode styles - ========================================================================== */ -.q_icon_list { - margin-bottom: 21px; -} - -.q_icon_list p{ - font-size: 15px; - line-height: 27px; - font-weight: 400; - margin: 0 0 10px; - padding: 0 0 0 38px; - position: relative; - color: #303030; -} - -.q_icon_list i { - background-color: #1abc9c; - - color: #fff; - font-size: 18px; - line-height: 27px; - height: 27px; - width: 27px; - text-align: center; - border-radius: 2em; - -webkit-border-radius: 2em; - -moz-border-radius: 2em; - -o-border-radius: 2em; -} - -.q_icon_list i.transparent { - background: transparent; - border: 0; - color: #ababab; -} - -/* ========================================================================== - Progress bar shortcode start styles - ========================================================================== */ -.q_progress_bar { - position: relative; - margin: 0 0 28px 0; - width: 100%; - overflow: hidden; - text-align: left; -} - -.q_progress_bar .progress_content_outer{ - background-color: #e3e3e3; - position: relative; - overflow: hidden; - height: 13px; -} - -.q_progress_bar .progress_content{ - position: absolute; - top: 0; - left: 0; - max-width: 100%; - overflow: hidden; - background-color: #1abc9c; - height: 13px; - box-sizing: border-box; -} - -.q_progress_bar .progress_title_holder { - position: relative; - margin: 0 0 7px 0; -} - -.q_progress_bar .progress_title { - display: inline-block; - z-index: 100; -} - -.q_progress_bar .progress_number_wrapper { - text-align: right; - position: absolute; - left: 0px; - z-index: 10; - opacity: 0; - filter: alpha(opacity=0); - color: #fff; -} - -.q_progress_bar .progress_number { - position: absolute; - right: 0; - font-size: 18px; - font-weight: 500; - top: -1px; -} -/* ========================================================================== - Progress bar shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Vertical progress bar shortcode start styles - ========================================================================== */ -.q_progress_bars_vertical .progress_content_outer { - height: 200px; - position: relative; - background-color: #e3e3e3; -} - - -.q_progress_bars_vertical .progress_number { - font-size: 18px; - line-height: 1em; - color: #303030; - display: block; - position: relative; - font-weight: 500; - margin-bottom: 14px; -} - -.q_progress_bars_vertical .progress_title { - margin-bottom: 0.7777777777777778em; - margin-top: 1em; -} - -.q_progress_bars_vertica .progress_text { - display: inline-block; - line-height: 18px; -} - -.q_progress_bars_vertical .progress_content_outer .progress_content { - display: inline-block; - width: 100%; - position: absolute; - bottom: 0; - left: 0px; - background-color: #1abc9c; - box-sizing: border-box; -} - -/* ========================================================================== - Vertical progress bar shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Counter shortcode start styles - ========================================================================== */ - -.q_counter_holder { - display: block; - opacity: 0; - filter: alpha(opacity=0); - -webkit-transition: opacity .4s ease 0s; - -moz-transition: opacity .4s ease 0s; - -o-transition: opacity .4s ease 0s; - padding: 20px 0; -} - -.q_counter_holder.boxed_counter { - border: 1px solid #eaeaea; - padding: 20px 40px; - background-color:#fff; -} - -.q_counter_holder.left { - text-align: left; -} - -.q_counter_holder.right { - text-align: right; -} - -.q_counter_holder.center { - text-align: center; - padding: 20px 40px; -} - -.q_counter_holder span.counter { - font-size: 60px; - line-height: 1em; - font-weight: 300; - color: #1abc9c; - display: inline-block !important; - height: 1em; -} -.q_counter_holder p.counter_text { - font-weight: 600; - text-transform: uppercase; - letter-spacing:1px; - margin: 12px 0 0 00; -} -.q_counter_holder .separator.small { - background-color: #eaeaea; - margin: 19px auto 0px auto; -} - -.q_counter_holder.left .separator.small { - margin-left: 0; - margin-right: auto; -} - -.q_counter_holder.right .separator.small { - margin-left: auto; - margin-right: 0; -} - -/* ========================================================================== - Counter shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Box Holder shortcode start styles - ========================================================================== */ -.q_box_holder{ - display: block; - position: relative; - border: 1px solid transparent; - z-index: 200; -} - -.q_box_holder.with_icon{ - border: 2px solid #c0c0c0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} - -.box_holder_inner{ - padding: 30px 20px; - display: block; -} - -.q_box_holder.with_icon .box_holder_inner.tiny{ - padding: 37px 20px 30px; -} - -.q_box_holder.with_icon .box_holder_inner.small{ - padding: 45px 20px 30px; -} - -.q_box_holder.with_icon .box_holder_inner.medium{ - padding: 58px 20px 30px; -} - -.q_box_holder.with_icon .box_holder_inner.large{ - padding: 71px 20px 30px; -} - -.q_box_holder.with_icon .box_holder_inner.very_large{ - padding: 85px 20px 30px; -} - -.box_holder_inner.left{ - text-align: left; -} - -.box_holder_inner.right{ - text-align: right; -} - -.box_holder_inner.center{ - text-align: center; -} - -.box_holder_icon{ - position: absolute; - display: block; - left: 50%; - top: 0; - z-index: 250; -} - -.box_holder_icon_inner{ - margin: -50% 0 0 -50%; -} - -.box_holder_icon_inner.circle, -.box_holder_icon_inner.square, -.box_holder_icon_inner.image{ - margin: -50% 0 0 -50%; -} - -.box_holder_icon_inner.circle .fa-stack, -.circle .icon_holder .fa-stack{ - -o-border-radius: 2em; - -moz-border-radius: 2em; - -webkit-border-radius: 2em; - -ms-border-radius: 2em; - border-radius: 2em; -} - -.box_holder_icon .fa-stack i{ - color: #1abc9c; -} - -.box_holder_icon_inner.tiny i.fa-circle{ - font-size: 40px; -} - -.box_holder_icon_inner.image.tiny img{ - height: 35px; -} - -.box_holder_icon_inner.image.small img{ - height: 52px; -} - -.box_holder_icon_inner.image.medium img{ - height: 78px; -} - -.box_holder_icon_inner.image.large img{ - height: 104px; -} - -.box_holder_icon_inner.image.very_large img{ - height: 130px; -} -/* ========================================================================== - Box Holder shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Button shortcode start styles - ========================================================================== */ -.qbutton, -.load_more a, -.blog_load_more_button a, -#submit_comment, -.drop_down .wide .second ul li .qbutton, -.drop_down .wide .second ul li ul li .qbutton { - position: relative; - display: inline-block; - width: auto; - height: 39px; - line-height: 39px; - margin: 0; - padding: 0px 23px; - border: 2px solid #303030; - font-size: 13px; - font-weight: 700; - font-family: inherit; - text-align: left; - color: #303030; - text-decoration: none; - cursor: pointer; - white-space: nowrap; - outline: none; - font-style: normal; - text-transform: uppercase; - letter-spacing: 1px; - - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - background-color: transparent; - -webkit-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -moz-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -ms-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -o-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - - -webkit-box-sizing: initial !important; - -moz-box-sizing: initial !important; - box-sizing: initial !important; -} - -input.qbutton { - line-height: 36px; -} - -.qbutton:hover, -.load_more a:hover, -.blog_load_more_button a:hover, -#submit_comment:hover, -.drop_down .wide .second ul li .qbutton:hover, -.drop_down .wide .second ul li ul li .qbutton:hover{ - background-color: #1abc9c; - border-color: #1abc9c; - color: #fff; - text-decoration: none; -} - -.qbutton.left { - text-align: left; -} - -.qbutton.right { - text-align: right; -} - -.qbutton.center { - text-align: center; -} - -/* Button sizes styles -========================================================================== */ -.qbutton.big_large{ - height: 58px; - line-height: 58px; - font-size: 20px; - padding: 0 22px; -} - -.qbutton.big_large_full_width{ - width:100%; - height: 90px; - line-height: 90px; - font-size: 20px; - padding:0; - text-align: center; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - -o-box-sizing: border-box; -} - -.qbutton.large { - height: 47px; - line-height: 47px; - font-size: 16px; - padding: 0px 29px; -} - -.qbutton.small { - height: 30px; - line-height: 30px; - font-size: 12px; - padding:0 17px; -} - -/* Button color styles -========================================================================== */ -.qbutton.white { - border-color: #fff; - color:#fff; -} -.qbutton.white:hover { - background-color: #1abc9c; - border-color: #1abc9c; -} - -.qbutton.green { - border-color: #1abc9c; - color:#fff; - background-color: #1abc9c; -} -.qbutton.green:hover { - background-color: #fff; - border-color: #fff; - color: #a2a2a2; -} -/* Button with icon styles -========================================================================== */ -.qbutton i { - margin: 0 0 0 10px; -} -.qbutton.large i { - margin: 0 0 0 17px; -} -.qbutton.medium i { - margin: 0 0 0 15px; -} -.qbutton.small i { - margin: 0 0 0 10px; -} -.qbutton.tiny i { - margin: 0 0 0 8px; -} -.qbutton.big_large i, -.qbutton.big_large_full_width i { - margin: 0 0 0 19px; -} - -/* Button usage custom styles -========================================================================== */ -#submit_comment, -.load_more.tiny a { - height: 39px; - line-height: 39px; - font-size: 12px; - padding: 0px 18px; -} - -#submit_comment { - line-height: 36px; -} - -/* ========================================================================== - Button end styles - ========================================================================== */ - -/* ========================================================================== - Pie Charts and Pie Charts With Icon start styles - ========================================================================== */ - -.easyPieChart { - position: relative; -} - -.easyPieChart canvas { - position: absolute; - top: 0; - left: 0; -} - -.q_pie_chart_holder, -.q_pie_chart_with_icon_holder{ - display: block; - margin: 0 0 30px; - opacity: 0; - filter: alpha(opacity=0); - -webkit-transition: opacity .3s ease 0s; - -moz-transition: opacity .3s ease 0s; - -o-transition: opacity .3s ease 0s; -} - -.q_percentage { - font-size: 35px; - font-weight: 500; - color: #303030; - text-align: center; - margin: 0 auto; - opacity: 0; - filter: alpha(opacity=0); - -webkit-transition: opacity .3s ease 0s; - -moz-transition: opacity .3s ease 0s; - -o-transition: opacity .3s ease 0s; -} - -.q_percentage_with_icon{ - color: #1abc9c; - text-align: center; - margin: 0 auto; - opacity: 0; - filter: alpha(opacity=0); - -webkit-transition: opacity .3s ease 0s; - -moz-transition: opacity .3s ease 0s; - -o-transition: opacity .3s ease 0s; - -webkit-backface-visibility: hidden; -} - -.q_pie_chart_holder .tocounter{ - float: none; - margin: 0; -} - -.q_percentage_with_icon i{ - float: none; - margin: 0; - vertical-align: middle !important; - color: #b9b9b9; -} - -.q_pie_chart_holder .pie_chart_text, -.q_pie_chart_with_icon_holder .pie_chart_text{ - text-align: center; - margin: 28px 0 0; -} - -.q_pie_chart_holder .pie_chart_text .pie_title, -.q_pie_chart_with_icon_holder .pie_chart_text .pie_title{ - margin: 0 0 0.35em; -} -.q_pie_chart_holder .separator.small { - background-color: #eaeaea; - margin: 10px auto 12px auto; -} -/* ========================================================================== - Pie Charts and Pie Charts With Icon end styles - ========================================================================== */ - -/* ========================================================================== - Image With Text start styles - ========================================================================== */ - -.image_with_text { - display: inline-block; - width: 100%; - position: relative; -} -.image_with_text img { - display: block; - margin: 0 0 22px 0; -} - -/* ========================================================================== - Image With Text end styles - ========================================================================== */ - -/* ========================================================================== - Call to action styles - ========================================================================== */ -.call_to_action { - position: relative; - display: block; - padding: 51px 21px; - background-color: #1abc9c; -} - -.call_to_action .two_columns_75_25 { - position: relative; -} - -.call_to_action .text_wrapper { - position:relative; -} - -.call_to_action .text_wrapper .call_to_action_text { - color: #fff; - letter-spacing: 1px; - font-size: 22px; - font-weight: 500; -} - -.call_to_action.with_icon .text_wrapper .call_to_action_text { - padding:0 0 0 54px; - line-height: 1em; -} -.call_to_action .text_wrapper .call_to_action_icon_holder{ - position:absolute; - height:100%; -} - -.call_to_action .text_wrapper .call_to_action_icon{ - display:table; - height:100%; -} - -.call_to_action .text_wrapper .call_to_action_icon_inner { - display:table-cell; - height:100%; - vertical-align:middle; -} - -.call_to_action .text_wrapper .call_to_action_icon_inner i { - color: #fff; -} - -.call_to_action .column2.button_wrapper { - text-align: right; -} - -.call_to_action .column2.button_wrapper .qbutton{ - position:absolute; - right:0; - top:50%; - margin:-21px 0 0 0; -} -.call_to_action .column2.button_wrapper .qbutton.small{ - margin-top:-17px; -} -.call_to_action .column2.button_wrapper .qbutton.large{ - margin-top:-25px; -} -.call_to_action .column2.button_wrapper .qbutton.big_large{ - margin-top:-31px; -} -/* ========================================================================== - Parallax shortcode styles - ========================================================================== */ - -.full_width .parallax_content{ - width: 1100px; - margin: 0px auto; -} - -section.section section.parallax{ - margin: -50px 0px; -} - -.boxed section.section section.parallax{ - margin: -50px -25px; -} - -.boxed .full_width .parallax_content{ - width: auto; - margin: 0px; - padding: 0px 25px; -} - -section.parallax_section_holder{ - position: static; - padding: 0px; - background-repeat: no-repeat; - background-color: transparent; - background-position: center 0px; - background-attachment: fixed; - overflow: hidden; -} - -.parallax_content, -.parallax_content_full_width -{ - z-index: 100; - position: relative; -} - -.parallax_content.left, -.parallax_content_full_width.left{ - text-align: left; -} - -.parallax_content.center, -.parallax_content_full_width.center{ - text-align: center; -} - -.parallax_content.right, -.parallax_content_full_width.right{ - text-align: right; -} - -/* ========================================================================== - Portfolio styles - ========================================================================== */ -.portfolio_single{ - display: block; - position: relative; -} - -.portfolio_single_text_holder, -.portfolio_detail, -.lightbox_single_portfolio{ - position: relative; -} - -.portfolio_single .flexslider, -.portfolio_single .portfolio_single_text_holder{ - margin: 0 0 40px; -} -.portfolio_single .portfolio_images .fluid-width-video-wrapper, -.portfolio_single .portfolio_images img{ - margin: 0 0 18px; -} - -.portfolio_single a.lightbox_single_portfolio.video_in_lightbox{ - display: block; -} - -.portfolio_single a.lightbox_single_portfolio > i{ - position: absolute; - top: 50%; - left: 50%; - display: inline-block; - vertical-align: middle; - font-size: 40px; - color: #fff; - margin: -20px 0 0 -15px; - z-index: 110; -} - -.portfolio_single .portfolio_container{ - position: relative; - z-index: 200; -} -.portfolio_single h2{ - margin: 0px 0 5px 0; -} - -.portfolio_single h3{ - margin: 0px 0 8px 0; -} - -.portfolio_detail.portfolio_single_follow { - position: relative; -} - -.portfolio_detail .info{ - padding: 0 0 9px; - margin: 0 0 9px; -} - -.portfolio_detail .info:last-child{ - border: 0px; -} - -.video_holder{ - position: relative; - width: 100%; - display: block; - min-height: 1px; -} - -.portfolio_single .video .mobile-video-image { - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - display: none; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; - z-index: 10; -} - -.portfolio_single .video{ - margin: 0 0 44px; - position: relative; -} - -.portfolio_single .video .video-wrap { - overflow: hidden; - position: relative; - width: 100%; - z-index: 10; -} - -.portfolio_single .video .video-wrap .mejs-poster { - background-size: cover!important; - -moz-background-size: cover!important; - -webkit-background-size: cover!important; - -o-background-size: cover!important; - width: 100% !important; - height: 100% !important; -} - -.portfolio_single .video .video-wrap .mejs-container { - background-color: transparent!important; - background-image: none!important; - height: 100% !important; - width: 100% !important; - overflow: hidden; -} - -.portfolio_single .video .video-wrap .mejs-mediaelement{ - background: none !important; - border: 0px !important; -} - -.portfolio_single .video .video-wrap .mejs-container .mejs-poster img { - max-width: none!important; - width: 100%!important; -} - -.portfolio_single .mejs-container .mejs-controls{ - visibility: visible !important; -} - -.portfolio_single .mejs-controls .mejs-volume-button .mejs-volume-slider{ - display: none !important; -} - -.flexslider .slides .mejs-poster img, -.portfolio_slider .portfolio_slides .mejs-poster img{ - display: none; -} - -.portfolio_single .flexslider .video .video-wrap{ - margin: 0px; -} - -/* Portfolio navigation styles - ========================================================================== */ -.portfolio_navigation { - display: inline-block; - width: 100%; - text-align: center; - padding: 28px 0 50px; - z-index: 100; - position: relative; -} - -.portfolio_navigation .portfolio_prev, -.portfolio_navigation .portfolio_next, -.portfolio_navigation .portfolio_button{ - display: inline-block; - height: 35px; - line-height: 35px; -} - -.portfolio_navigation .portfolio_prev{ - position: absolute; - left: 0; -} - -.portfolio_navigation .portfolio_next{ - position: absolute; - right: 0; -} - -.portfolio_navigation .portfolio_prev a, -.portfolio_navigation .portfolio_next a{ - position: relative; - display: inline-block; - width: 38px; - height: 38px; - line-height: 38px; - margin: 0 11px 0 0; - text-align:center; - font-size: 18px; - color: #b4b4b4; - text-decoration: none; - text-transform: uppercase; - cursor: pointer; - white-space: nowrap; - border: 2px solid #e5e5e5; - outline: none; - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; -} - -.portfolio_navigation .portfolio_prev a:hover, -.portfolio_navigation .portfolio_next a:hover { - color: #303030; - background-color: #e3e3e3; - border-color: #e3e3e3; -} - -.portfolio_navigation .portfolio_button a{ - background-image: url('img/portfolio_list_button.png'); - background-position: 0 0; - background-repeat: no-repeat; - width: 19px; - display: block; - height: 19px; - margin: 11px 0 0 0; - - -webkit-transition: background-image 0.3s ease-in-out; - -moz-transition: background-image 0.3s ease-in-out; - -ms-transition: background-image 0.3s ease-in-out; - -o-transition: background-image 0.3s ease-in-out; - transition: background-image 0.3s ease-in-out; -} -.portfolio_navigation .portfolio_button a:hover{ - background-image: url('img/portfolio_list_button_hover.png'); -} -@media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { - .portfolio_navigation .portfolio_button a{ - background-image: url('img/portfolio_list_button@1_5x.png'); - -o-background-size: 19px 19px; - -webkit-background-size: 19px 19px; - -moz-background-size: 19px 19px; - background-size: 19px 19px; - } - .portfolio_navigation .portfolio_button a:hover{ - background-image: url('img/portfolio_list_button_hover@1_5x.png'); - } -} - -@media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { - .portfolio_navigation .portfolio_button a{ - background-image: url('img/portfolio_list_button@2x.png'); - -o-background-size: 19px 19px; - -webkit-background-size: 19px 19px; - -moz-background-size: 19px 19px; - background-size: 19px 19px; - } - .portfolio_navigation .portfolio_button a:hover{ - background-image: url('img/portfolio_list_button_hover@2x.png'); - } -} - -.portfolio_navigation .portfolio_prev a:hover, -.portfolio_navigation .portfolio_next a:hover{ - background-image: url('img/button-bg-px.png') !important; -} - -.portfolio_social_holder{ - width:100%; - display: inline-block; -} - -.portfolio_single .portfolio_social_holder .portfolio_share, -.portfolio_single .portfolio_social_holder .portfolio_like{ - display: inline-block; - margin: 0; -} - -.portfolio_gallery { - display: inline-block; - width: 100%; - position: relative; - margin: 0 0 15px 0; -} -.portfolio_single .portfolio_gallery{ - margin: 0 0 3px 0; -} -.portfolio_gallery a { - position: relative; - float: left; - display: inline-block; - overflow: hidden; - -webkit-backface-visibility: hidden; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); -} - -.portfolio_gallery a.v2 { - width: 49%; - margin: 0 2% 2% 0; -} - -.portfolio_gallery a.v3 { - width: 32%; - margin: 0 2% 2% 0; -} - -.portfolio_gallery a.v4 { - width: 23.5%; - margin: 0 2% 2% 0; -} - -.portfolio_gallery a.v2:nth-child(2n), -.portfolio_gallery a.v3:nth-child(3n), -.portfolio_gallery a.v4:nth-child(4n) { - margin: 0 0 2% 0; -} - -.portfolio_gallery a img, -.portfolio_gallery a frame { - position: relative; - display: block; - width: 100%; - z-index: 100; -} - -.portfolio_gallery iframe{ - min-height: 200px; -} - -.portfolio_gallery a .gallery_text_holder{ - background-color: #000; - background-color: rgba(0, 0, 0, 0.50); - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - display: inline-block; - z-index: 200; - opacity: 0; - filter: alpha(opacity=0); - visibility: visible; - -webkit-transition: opacity .4s; - -moz-transition: opacity .4s; - -o-transition: opacity .4s; - -ms-transition: opacity .4s; -} - -.portfolio_gallery a img{ - -webkit-transition: all 0.3s ease-out; - -moz-transition: all 0.3s ease-out; - -o-transition: all 0.3s ease-out; - transition: all 0.3s ease-out; -} - -.portfolio_gallery a:hover .gallery_text_holder{ - opacity: 1; - filter: alpha(opacity=100); -} - -.portfolio_gallery a .gallery_text_inner{ - display: table; - text-align: center; - vertical-align: middle; - width: 100%; - height: 100%; -} - -.portfolio_gallery a .gallery_text_inner h6{ - display: table-cell; - text-align: center; - vertical-align: middle; - width: 100%; - height: 100%; - margin: 0; - padding: 0px 15px; - color: #fff; -} - -.projects_holder_outer{ - margin: 0; - display: block; - width: 100%; -} -.projects_holder_outer .container .container_inner{ - padding: 0px 0px 0px 0px; -} - -.full_width .projects_holder_outer.v6 .hover_text, -.full_width .projects_holder_outer.v5 .hover_text, -.full_width .projects_holder_outer.v4 .hover_text, -.full_width .projects_holder_outer.v5 .standard, -.full_width .projects_holder_outer.v6 .standard, -.full_width .projects_holder_outer.v4 .standard { - width: 95%; - margin: 0 auto; -} - -.full_width .section_inner .projects_holder_outer.v6 .hover_text, -.full_width .section_inner .projects_holder_outer.v5 .hover_text, -.full_width .section_inner .projects_holder_outer.v4 .hover_text, -.full_width .section_inner .projects_holder_outer.v5 .standard, -.full_width .section_inner .projects_holder_outer.v6 .standard, -.full_width .section_inner .projects_holder_outer.v4 .standard { - width: 100%; -} - -.full_width .projects_holder_outer.v6 .hover_text.no_space, -.full_width .projects_holder_outer.v5 .hover_text.no_space, -.full_width .projects_holder_outer.v4 .hover_text.no_space{ - width: 100%; - margin: 0; -} - -.projects_holder{ - font-size: 0.1px; - line-height: 0; - list-style-type: none; - text-align: justify; -} - -.projects_holder:after, -.projects_holder:before{ - content: ""; - display: inline-block !important; - width: 100%; -} - -.projects_holder > .mix{ - /*display: none;*/ - visibility: hidden; - position: relative; - vertical-align: top; - -webkit-transition: all 0.7s ease-out; - -moz-transition: all 0.7s ease-out; - -o-transition: all 0.7s ease-out; - transition: all 0.7s ease-out; - text-align: left; -} - -.projects_holder.hideItems > .mix{ - display: none; -} - -.projects_holder.hover_text.no_space:not(.portfolio_full_image) > .mix{ - float: left; -} - -.projects_holder .mix .image{ - position: relative; - display: block; - overflow: hidden; - width: 100%; - -moz-transform: translateZ(0px); - -webkit-transform: translateZ(0px); -} - -.projects_holder article .image img { - position: relative; - display: block; - width: 100%; - z-index: 100; -} - -.projects_holder article .image img, -.portfolio_slider .portfolio_slides li.item img { - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); - - -webkit-transition: -webkit-transform 0.3s ease-in-out; - -moz-transition: -moz-transform 0.3s ease-in-out; - -ms-transition: -ms-transform 0.3s ease-in-out; - -o-transition: -o-transform 0.3s ease-in-out; - transition: transform 0.3s ease-in-out; - -} - -.projects_holder.hover_text.no_space article .image img{ - margin:0 1px; -} - -.projects_holder article .image_holder:hover .image img, -.portfolio_slider .portfolio_slides li.item:hover img { - -webkit-transform: scale(1.1); - -moz-transform: scale(1.1); - -ms-transform: scale(1.1); - -o-transform: scale(1.1); - transform: scale(1.1); -} - -.projects_holder article .image_holder, -.projects_holder article .portfolio_description{ - display: block; - position: relative; -} - -.projects_holder article .portfolio_description{ - padding:20px 0 22px; - text-align:center; - background-color:#fff; - border-style:none; - border-top:none !important; - border-width:1px; - border-color: #fefefe; -} - -.projects_holder article .portfolio_description.text_align_left { - text-align: left; -} - -.projects_holder article .portfolio_description.text_align_center { - text-align: center; -} - -.projects_holder article .portfolio_description.text_align_right { - text-align: right; -} - -.standard_no_space.projects_holder article .portfolio_description{ - margin: 0 -1px 0 0; -} - -.projects_holder article .portfolio_description .portfolio_title { - display: block; - margin:0 0 7px 0; -} - -.portfolio_slider .image_holder .separator.small{ - margin: 10px auto; - background-color: #fff; -} -.projects_holder article .hover_feature_holder_title .separator.small, -.projects_masonry_holder article .hover_feature_holder_title .separator.small{ - background-color: #fff; - margin-top: 10px; - margin-bottom: 10px; -} - -.projects_holder article .portfolio_description .separator.small{ - margin-top: 10px; - margin-bottom: 10px; -} - -.wpb_column>.wpb_wrapper .portfolio_slider .image_holder .separator.small { - background-color: #fff; -} - -.portfolio_slider .image_holder .separator.small.transparent{ - background-color: transparent !important; -} -.projects_holder.hover_text article .hover_feature_holder_title .separator{ - background-color: #fff; -} - -.projects_holder.hover_text article .hover_feature_holder_title .portfolio_title a, -.projects_holder.hover_text article span.text_holder span.text_inner .hover_feature_holder_title .project_category{ - color: #fff; -} -.projects_holder.hover_text article span.text_holder span.text_inner .hover_feature_holder_title .project_category{ - font-weight:500; -} -.projects_holder.hover_text article .hover_feature_holder_title .portfolio_title{ - margin:0 0 7px; -} -.projects_holder article .portfolio_description .project_category, -.projects_holder.hover_text article .project_category { - line-height: 22px; - display: block; - font-size: 13px; - font-weight:500; -} - -.portfolio_single .portfolio_like{ - position: relative; - display: inline-block; - cursor: pointer; - padding: 0px; - -} - -.portfolio_single .dots{ - padding: 0 7px 0 4px; -} -.portfolio_single .dots i{ - font-size: 3px; - vertical-align: middle; -} -.portfolio_single .portfolio_like a{ - display: block; - font-size: 13px; - line-height: 13px; - text-align: center; -} - -.portfolio_single .portfolio_like span{ - line-height: 19px; - -} - -.portfolio_slider .portfolio_like a:hover i, -.portfolio_slider .portfolio_like span{ - color: #e0e0e0; -} - -.projects_holder article .portfolio_like a, -.projects_holder article .portfolio_like:hover a { - color: #fff; -} - -.projects_holder article span.text_holder { - background-color: #000; - background-color: rgba(21, 21, 21, 0.78); - bottom: 0; - display: inline-block; - height: 100%; - left: 0; - opacity: 0; - position: absolute; - transition: opacity 0.4s ease-in-out; - -webkit-transition: opacity 0.4s ease-in-out; - -moz-transition: opacity 0.4s ease-in-out; - -o-transition: opacity 0.4s ease-in-out; - -ms-transition: opacity 0.4s ease-in-out; - visibility: visible; - overflow: hidden; - width: 100%; - z-index: 200; -} - -.touch .projects_holder article span.text_holder{ - display: none !important; - height: 0 !important; - width: 0 !important; - opacity: 0 !important; - visibility: hidden !important; -} - -.projects_holder article:hover span.text_holder{ - height:100% !important; -} - -.projects_holder article .image_holder:hover span.text_holder{ - opacity: 1; - filter: alpha(opacity=100); -} - -.projects_holder.hover_text.with_mask article .image_holder:hover .image_hover{ - opacity: 0; - filter: alpha(opacity=0); -} - -.projects_holder article span.text_holder span.text_outer{ - display: table; - text-align: center; - vertical-align: middle; - width: 100%; - height: 100%; - overflow:hidden; - -} - -.projects_holder article span.text_holder span span.text_inner{ - display: table-cell; - text-align: center; - vertical-align: middle; - width: 100%; - height: 100%; - margin: 0; - padding: 0; -} - -.projects_holder article span.text_holder span span.text_inner .project_category{ - color: #A6A6A6; - display: block; - font-size: 13px; - line-height: 22px; -} - -.projects_holder article .feature_holder, -.projects_holder article .feature_holder .feature_holder_icons{ - display: inline-block; -} - -.projects_holder.hover_text article .feature_holder{ - width: 100%; -} - -.projects_holder.hover_text article .feature_holder .feature_holder_icons{ - margin:20px 0 0 0; -} - -.portfolio_slider, -.portfolio_slides .image_holder{ - position: relative; - display: block; - -webkit-backface-visibility: hidden; -} - -.portfolio_slides .image_pixel_hover{ - position: absolute; - height: 100%; - width: 100%; - display: block; - background-color: transparent; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - z-index: 100; -} - -.touch .portfolio_slides .image_pixel_hover{ - display: none !important; -} - -.portfolio_slides li:hover .image_pixel_hover{ - background-color: #000; - background-color: rgba(21, 21, 21, 0.78); -} - -.portfolio_slides .image_holder .image { - position: relative; - display: block; - overflow: hidden; - width: 100%; - -webkit-transition: -webkit-transform 0.4s; - -moz-transition: -moz-transform 0.4s; - transition: transform 0.4s; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; -} - -.portfolio_slides .hover_feature_holder{ - position: absolute; - display: block; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 101; -} - -.touch .portfolio_slides .hover_feature_holder{ - display: none !important; -} - -.portfolio_slides .hover_feature_holder_icons{ - position: relative; - opacity: 0; - text-align: center; - display: inline-block; - width: 100%; - margin: 0 0 30px; - -webkit-transition: opacity .4s ease-in-out 0.1s; - -moz-transition: opacity .4s ease-in-out 0.1s; - -o-transition: opacity .4s ease-in-out 0.1s; - -ms-transition: opacity .4s ease-in-out 0.1s; - transition: opacity .4s ease-in-out 0.1s; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); - - display: none; -} - -.portfolio_slides li:hover .hover_feature_holder_icons { - opacity: 1; -} - -.portfolio_slides .hover_feature_holder_icons_inner { - display: inline-block; - position: relative; -} - -.portfolio_slides .hover_feature_holder_outer { - position: relative; - opacity: 1 !important; - top: 0; - height: 100%; - display: table; - width: 100%; -} - -.portfolio_slides .hover_feature_holder_inner { - height: 100%; - width: 100%; - top: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - -o-box-sizing: border-box; - box-sizing: border-box; - opacity: 0; - display: table-cell; - vertical-align: middle; - padding: 0 5%; - - text-align: center; - color: #fff; - - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; -} - -.portfolio_slides .hover_feature_holder_inner .portfolio_title { - text-transform: uppercase; - letter-spacing: 1px; -} - -.portfolio_slides .hover_feature_holder_inner .portfolio_title a { - color: #fff; -} - -.portfolio_slides .hover_feature_holder_inner .qbutton { - margin-top: 24px; - margin-left: 5px; - margin-right: 5px; -} - -.portfolio_slides .hover_feature_holder_inner .qbutton:hover { - border-color: #1abc9c; -} - -.portfolio_slides li:hover .hover_feature_holder_inner{ - opacity: 1; -} - -.projects_holder.hover_text article .image_holder{ - overflow: hidden; - -} -.projects_holder.hover_text.no_space article .image_holder{ - margin: 0 -1px; -} -.projects_holder article a.lightbox, -.projects_holder article a.preview, -.projects_holder article .portfolio_like, -.portfolio_slider a.lightbox, -.portfolio_slider a.preview, -.portfolio_slider .portfolio_like{ - position: relative; - display: inline-block; - margin:0 0 5px 0; - -webkit-backface-visibility: hidden; -} - -.projects_holder article a.lightbox, -.portfolio_slider a.lightbox{ - margin: 0 10px 0 0; -} - -.projects_holder article .portfolio_like, -.portfolio_slider .portfolio_like{ - margin: 0 0 0 10px; -} - -.projects_holder article .portfolio_like i, -.portfolio_slider .portfolio_like i{ - line-height: 20px; - margin: 4px 0 0 0; -} - -.portfolio_like .qode-like-count span{ - display:none; -} - - -.projects_holder article .portfolio_like a:hover, -.portfolio_slider .portfolio_like a:hover{ - /*opacity: 0.7;*/ - /*filter: alpha(opacity=70);*/ -} - -.projects_holder article .portfolio_like .qode-like-count, -.portfolio_slider article .portfolio_like .qode-like-count{ - font-size: 13px; - line-height: 13px; - color: #fff; -} - -.projects_holder .filler { - display: inline-block; - height: 0px; -} - -.projects_holder.v6 .mix, -.projects_holder.v6.hover_text .mix{ - width: 15.7%; - margin: 0 0 1.2%; -} - -.projects_holder.v6.hover_text .mix{ - margin: 0 0 1.7%; -} - -.projects_holder.v6 .filler, -.projects_holder.v6.hover_text .filler{ - width: 15.7%; -} - -.projects_holder.v6.standard_no_space .mix, -.projects_holder.v6.hover_text.no_space .mix{ - width: 16.66%; - margin: 0; -} - -.projects_holder.v6.standard_no_space .mix{ - margin: 0 0 0%; -} - -.projects_holder.v6.standard_no_space .filler, -.projects_holder.v6.hover_text.no_space .filler{ - width: 16.66%; -} - -.safari_browser .projects_holder.v6.standard_no_space .mix, -.safari_browser .projects_holder.v6.hover_text.no_space .mix{ - width: 16.6%; -} - -.safari_browser .projects_holder.v6.standard_no_space .filler, -.safari_browser .projects_holder.v6.hover_text.no_space .filler{ - width: 16.6%; -} - -.projects_holder.v5 .mix, -.projects_holder.v5.hover_text .mix{ - width: 18%; - margin: 0 0 2.9%; -} - -.projects_holder.v5.hover_text .mix{ - margin: 0 0 2%; -} - -.projects_holder.v5 .filler, -.projects_holder.v5.hover_text .filler{ - width: 18.5%; -} - -.projects_holder.v5.standard_no_space .mix, -.projects_holder.v5.hover_text.no_space .mix{ - width: 19.99%; - margin: 0; -} - -.projects_holder.v5.standard_no_space .mix{ - margin: 0 0 0%; -} - -.projects_holder.v5.standard_no_space .filler, -.projects_holder.v5.hover_text.no_space .filler{ - width: 19.99%; -} - -.safari_browser .projects_holder.v5.standard_no_space .mix, -.safari_browser .projects_holder.v5.hover_text.no_space .mix{ - width: 19.93%; -} - -.safari_browser .projects_holder.v5.standard_no_space .filler, -.safari_browser .projects_holder.v5.hover_text.no_space .filler{ - width: 19.93%; -} - - - -.projects_holder.v4 .mix, -.projects_holder.v4.hover_text .mix{ - width: 23.5%; - margin: 0 0 2.5%; -} - -.projects_holder.v4.hover_text .mix{ - margin: 0 0 2.2%; -} - -.projects_holder.v4 .filler, -.projects_holder.v4.hover_text .filler{ - width: 23.5%; -} - -.projects_holder.v4.standard_no_space .mix, -.projects_holder.v4.hover_text.no_space .mix{ - width: 24.99%; - margin: 0; -} - -.projects_holder.v4.standard_no_space .mix{ - margin: 0 0 0; -} - -.projects_holder.v4.standard_no_space .filler, -.projects_holder.v4.hover_text.no_space .filler{ - width: 24.99%; -} - - - -.projects_holder.v3 .mix, -.projects_holder.v3.hover_text .mix{ - width: 32%; - margin: 0 0 2.4%; -} - -.projects_holder.v3.hover_text .mix{ - margin: 0 0 2.2%; -} - -.projects_holder.v3 .filler, -.projects_holder.v3.hover_text .filler{ - width: 32%; -} - -.projects_holder.v3.standard_no_space .mix, -.projects_holder.v3.hover_text.no_space .mix{ - width: 33.32%; - margin: 0; -} - -.projects_holder.v3.standard_no_space .mix{ - margin: 0 0 0%; -} - -.projects_holder.v3.standard_no_space .filler, -.projects_holder.v3.hover_text.no_space .filler{ - width: 33.32%; -} - -.safari_browser .projects_holder.v3.standard_no_space .mix, -.safari_browser .projects_holder.v3.hover_text.no_space .mix{ - width: 33.3%; -} - -.safari_browser .projects_holder.v3.standard_no_space .filler, -.safari_browser .projects_holder.v3.hover_text.no_space .filler{ - width: 33.3%; -} - -.projects_holder.v2 .mix, -.projects_holder.v2.hover_text .mix{ - width: 49%; - margin: 0 0 2.4%; -} - -.projects_holder.v2.hover_text .mix{ - margin: 0 0 2.1%; -} - -.projects_holder.v2 .filler, -.projects_holder.v2.hover_text .filler{ - width: 49%; -} - -.projects_holder.v2.standard_no_space .mix, -.projects_holder.v2.hover_text.no_space .mix{ - width: 49.99%; - margin: 0; -} - -.projects_holder.v2.standard_no_space .mix{ - margin: 0 0 0%; -} - -.projects_holder.v2.standard_no_space .filler, -.projects_holder.v2.hover_text.no_space .filler{ - width: 49.99%; -} - -.portfolio_paging, .portfolio_paging_loading { - text-align: center; - margin: 40px 0 0; -} - -.portfolio_paging_loading { display: none; } - -.portfolio_with_space .portfolio_paging, -.portfolio_with_space .portfolio_paging_loading { - margin: 15px 0 0; -} - -.filter_outer{ - display: table; - width: 100%; - position: relative; - height: 37px; - margin: -30px 0 40px; - text-align:center; -} - -.vertical_menu_enabled .full_width .filter_outer{ - margin: 0 0 40px; -} - -.filter_holder { - display:table-cell; - vertical-align: middle; -} - -.filter_holder ul { - display: inline-block; - list-style: none; -} - -.filter_holder ul li { - cursor: pointer; - display: block; - margin: 0; - float:left; - text-align: center; -} - -.filter_holder ul li span { - display: inline-block; - padding: 0 22px; - position: relative; - letter-spacing:1px; - text-transform: uppercase; - font-weight: 600; -} - -.filter_holder ul li.active span{ - color:#1abc9c !important; -} - -.filter_holder ul li:hover span{ - color:#1abc9c !important; -} - -/* Portfolio Masonry styles - ========================================================================== */ - -.projects_masonry_holder{ - opacity: 0; -} - -.projects_masonry_holder .portfolio_masonry_item, -.projects_masonry_holder .portfolio_masonry_item.large_height{ - width: 33.33%; -} - -.projects_masonry_holder .portfolio_masonry_item.large_width, -.projects_masonry_holder .portfolio_masonry_item.large_width_height{ - width: 66.66%; -} - -.full_width .projects_masonry_holder .portfolio_masonry_item, -.full_width .projects_masonry_holder .portfolio_masonry_item.large_height{ - width: 19.96%; -} - -.full_width .projects_masonry_holder .portfolio_masonry_item.large_width, -.full_width .projects_masonry_holder .portfolio_masonry_item.large_width_height{ - width: 39.92%; -} - -.full_width .projects_masonry_holder.gs4 .portfolio_masonry_item, -.full_width .projects_masonry_holder.gs4 .portfolio_masonry_item.large_height, -.projects_masonry_holder.gs4 .portfolio_masonry_item, -.projects_masonry_holder.gs4 .portfolio_masonry_item.large_height -{ - width: 25%; -} - -.full_width .projects_masonry_holder.gs4 .portfolio_masonry_item.large_width, -.full_width .projects_masonry_holder.gs4 .portfolio_masonry_item.large_width_height, -.projects_masonry_holder.gs4 .portfolio_masonry_item.large_width, -.projects_masonry_holder.gs4 .portfolio_masonry_item.large_width_height -{ - width: 50%; -} - -.projects_masonry_holder:after, -.projects_masonry_holder .portfolio_masonry_item:after { - clear: both; - content: ""; - display: block; - height: 0; - visibility: hidden; -} - -.projects_masonry_holder .image_holder img{ - vertical-align: top; - width: 100%; - height: auto; -} - -.projects_masonry_holder .image_holder{ - margin: 0px -1px 0px 0px; -} - -.projects_masonry_holder .text_holder{ - position: absolute; - top: 0; - left: 0; - width: 100.2%; /* beacuse there is one pixel o right side that is not covered with hover shader */ - height: 100%; - background-color: rgba(0,0,0,0.8); - text-align: center; - transition: opacity 0.4s ease-in-out; - -webkit-transition: opacity 0.4s ease-in-out; - -moz-transition: opacity 0.4s ease-in-out; - -o-transition: opacity 0.4s ease-in-out; - -ms-transition: opacity 0.4s ease-in-out; - visibility: visible; - overflow: hidden; - z-index: 200; - opacity: 0; - filter: alpha(opacity=0); -} - -.projects_masonry_holder .text_holder .text_outer{ - display: table; - text-align: center; - vertical-align: middle; - width: 100%; - height: 100%; - overflow: hidden; -} - -.projects_masonry_holder .text_holder .text_inner{ - display: table-cell; - text-align: center; - vertical-align: middle; - width: 100%; - height: 100%; - margin: 0; - padding: 0; -} - -.projects_masonry_holder article.portfolio_masonry_item:hover .text_holder{ - opacity: 1; - filter: alpha(opacity=100); -} - -.projects_masonry_holder .portfolio_title { - margin: 0 0 7px; -} - -.projects_masonry_holder .portfolio_title a{ - color: #fff; -} - -.projects_masonry_holder .project_category, -.masonry_with_space_only_image .project_category { - font-weight: 500; -} - -.projects_masonry_holder .separator, -.masonry_with_space_only_image .separator{ - background-color: #fff; -} - -.projects_masonry_holder .feature_holder_icons { - margin: 20px 0 0 0; - display: inline-block; -} - -.projects_masonry_holder .feature_holder { - width: 100%; - display: inline-block; -} - -.projects_masonry_holder a.lightbox { - margin: 0 10px 0 0; -} - -.projects_masonry_holder .portfolio_like { - margin: 0 0 0 10px; -} - -.projects_masonry_holder .portfolio_like a, -.projects_masonry_holder .portfolio_like:hover a { - color: #fff; -} - -.masonry_with_space .projects_holder{ - position: relative; - opacity: 0; -} - -.masonry_with_space .projects_holder .mix{ - display: block; - padding: 0px 7px; - margin: 0px 0px 14px 0px !important; - -webkit-transition: none; - -moz-transition: none; - -o-transition: none; - transition: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - visibility: visible; -} - -.masonry_with_space .projects_holder.v6 .mix{ - width: 16.66%; -} - -.masonry_with_space .projects_holder.v5 .mix{ - width: 20%; -} - -.masonry_with_space .projects_holder.v4 .mix{ - width: 25%; -} - -.masonry_with_space .projects_holder.v3 .mix{ - width: 33.33%; -} - -.masonry_with_space .projects_holder.v2 .mix{ - width: 49.99%; -} - -/*----------------------Portfolio "Fade - one by one" loading type-------------------------------*/ - -.projects_holder_outer:not(.masonry_with_space) .projects_holder.portfolio_one_by_one article{ - opacity: 0 !important; -} - -.projects_holder_outer:not(.masonry_with_space) .projects_holder.portfolio_one_by_one article.show{ - opacity: 1 !important; -} - -.projects_holder_outer.masonry_with_space .projects_holder.portfolio_one_by_one article, -.projects_masonry_holder.portfolio_one_by_one article{ - opacity: 0; -} - -.projects_holder_outer.masonry_with_space .projects_holder.portfolio_one_by_one article.show, -.projects_masonry_holder.portfolio_one_by_one article.show{ - opacity: 1; -} -/*---------------------Portfolio "Slide from top - diagonal" loading type-------------------------*/ - -.projects_holder.slide_from_top article{ - overflow:hidden; -} - -.projects_holder.slide_from_top article .image_holder, -.projects_holder.slide_from_top article .portfolio_description{ - opacity: 0 !important; - -webkit-transform: translateY(-70%); - transform: translateY(-70%); - -moz-transition: -moz-transform 0.4s cubic-bezier(.4,0,.2,1), opacity 0.4s cubic-bezier(.4,0,.2,1); - -webkit-transition: -webkit-transform 0.4s cubic-bezier(.4,0,.2,1), opacity 0.4s cubic-bezier(.4,0,.2,1); - transition: transform 0.4s cubic-bezier(.4,0,.2,1), opacity 0.4s cubic-bezier(.4,0,.2,1); -} - -.projects_holder.slide_from_top article.show .image_holder, -.projects_holder.slide_from_top article.show .portfolio_description{ - opacity: 1 !important; - -webkit-transform: translateY(0); - transform: translateY(0); -} - -/*---------------------Portfolio "Fade - diagonal" loading type-------------------------*/ - -.projects_holder.diagonal_fade article{ - opacity: 0 !important; - -moz-transition: opacity 0.4s ease-in-out, -moz-transform 0.4s ease-in-out; - -webkit-transition: opacity 0.4s ease-in-out, -webkit-transform 0.4s ease-in-out; - transition:opacity 0.4s ease-in-out, transform 0.4s ease-in-out; - -webkit-transform: scale(0.8); - -moz-transform: scale(0.8); - transform: scale(0.8); -} - -.projects_holder.diagonal_fade article.show{ - opacity: 1 !important; - -webkit-transform: scale(1); - transform: scale(1); -} - -/*---------------------Portfolio "Slide from left - random" loading type-------------------------*/ - -.projects_holder.slide_from_left article{ - overflow:hidden; -} - -.projects_holder.slide_from_left article .image_holder, -.projects_holder.slide_from_left article .portfolio_description{ - opacity: 0 !important; - -webkit-transform: translateX(-100%); - transform: translateX(-100%); - -moz-transition: -moz-transform 0.3s cubic-bezier(.4,0,.2,1), opacity 0.3s cubic-bezier(.4,0,.2,1); - -webkit-transition: -webkit-transform 0.3s cubic-bezier(.4,0,.2,1), opacity 0.3s cubic-bezier(.4,0,.2,1); - transition: transform 0.3s cubic-bezier(.4,0,.2,1), opacity 0.3s cubic-bezier(.4,0,.2,1); -} - -.projects_holder.slide_from_left article.show .image_holder, -.projects_holder.slide_from_left article.show .portfolio_description{ - opacity: 1 !important; - -webkit-transform: translateX(0); - transform: translateX(0); -} - -/*---------------------Portfolio "Fade from bottom" loading type-------------------------*/ - -.projects_holder.portfolio_fade_from_bottom article, -.projects_masonry_holder.portfolio_fade_from_bottom article { - opacity: 0; - -ms-transform: translateY(150px); - -webkit-transform: translateY(150px); - transform: translateY(150px); - -ms-transition: opacity 0.8s ease, -ms-transform 0.8s ease !important; - -webkit-transition: opacity 0.8s ease, -webkit-transform 0.8s ease !important; - transition: opacity 0.8s ease, transform 0.8s ease !important; -} - -.projects_holder.portfolio_fade_from_bottom article.show, -.projects_masonry_holder.portfolio_fade_from_bottom article.show { - opacity: 1; - margin-top: 0px; - -ms-transform: translateY(0px); - -webkit-transform: translateY(0px); - transform: translateY(0px); -} - -/* ========================================================================== - #Portfolio Masonry With Space Without Description - ========================================================================== */ -.masonry_with_space_only_image .hover_feature_holder_title_inner . portfolio_title { - margin-bottom: 7px; -} - -.masonry_with_space_only_image .hover_feature_holder_title_inner .portfolio_title, -.masonry_with_space_only_image .hover_feature_holder_title_inner .portfolio_title a, -.masonry_with_space_only_image .projects_holder article span.text_holder span span.text_inner .project_category { - color: #fff; -} - -.projects_holder.standard article .item_holder.image_text_zoom_hover .project_category { - margin-bottom: 10px; -} - -.masonry_with_space_only_image .feature_holder { - margin-top: 30px; -} -/* ========================================================================== - #End of Portfolio Masonry With Space Without Description - ========================================================================== */ - - - - -/* ========================================================================== - #Portfolio Hover effects styles - ========================================================================== */ - -.portfolio_main_holder .item_holder { - position: relative; -} -.projects_holder article a.portfolio_link_class, -.projects_masonry_holder article a.portfolio_link_class { - position: absolute; - width: 100%; - height: 100%; -} -.portfolio_main_holder .item_holder .text_holder { - position: absolute; -} -.portfolio_main_holder .project_category { - margin: 0; - display: block; - line-height: 1; - font-size: 12px; -} -.portfolio_main_holder .item_holder .text_holder_outer { - display: table; - width:100%; - height: 100%; -} -.portfolio_main_holder .item_holder .text_holder_inner{ - display: table-cell; - vertical-align: middle; - text-align:center; -} -.portfolio_main_holder .item_holder .portfolio_shader { - position: absolute; - width:100%; - height: 100%; - background-color: rgba(21,21,21,0.78); -} - -.portfolio_main_holder .item_holder .icons_holder{ - font-family: "Raleway",sans-serif; - /* this css is here to overwrite other font-family (from body) which can make problem in icon height */ -} - -.portfolio_main_holder .item_holder .icons_holder a { - text-align: center; -} -.portfolio_main_holder .item_holder .portfolio_title { - line-height:1.25em; -} - -.projects_holder.standard article .project_category, -.projects_holder.standard_no_space article .project_category, -.portfolio_slider_holder.standard li .project_category{ - margin:10px 0 0 0; -} - -.projects_holder article a.portfolio_link_class, .projects_masonry_holder article a.portfolio_link_class { - z-index: 5; - left: 0; -} - -.portfolio_main_holder article .icons_holder a.portfolio_lightbox:before, -.portfolio_slides .icons_holder a.portfolio_lightbox:before{ - font-family: 'FontAwesome'; - content: "\f067"; - line-height: inherit; -} - -.portfolio_main_holder article .icons_holder a.qode-like:before, -.portfolio_slides .icons_holder a.qode-like:before{ - font-family: 'FontAwesome'; - content: "\f08a"; - line-height: inherit; -} - -.portfolio_main_holder article .icons_holder a.qode-like.liked:before, -.portfolio_slides .icons_holder a.qode-like.liked:before{ - font-family: "FontAwesome"; - content: "\f004"; - line-height: inherit; -} - - -.portfolio_main_holder article .icons_holder a.preview:before, -.portfolio_slides .icons_holder a.preview:before { - content: "\f0c1"; - font-family: "FontAwesome"; - line-height: inherit; -} - -.portfolio_main_holder .item_holder .portfolio_title a, -.portfolio_main_holder .item_holder .project_category { - color: #fff; -} - -.portfolio_main_holder .item_holder .portfolio_title { - margin-bottom: 15px; -} - - - - -/* #Subtle vertical hover - ========================================================================== */ -.projects_holder article .item_holder.subtle_vertical_hover a.portfolio_link_class, -.projects_masonry_holder article .item_holder.subtle_vertical_hover a.portfolio_link_class { - z-index: 5 -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .image_holder { - z-index: 2 -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .text_holder { - font-size: 14px; - width: 100%; - position: absolute; - left: 0; - height: 100%; - background-color: transparent; - top: 0; - text-align: center; - box-sizing: border-box; - z-index: 4; - opacity: 0; -} - -.portfolio_main_holder article .item_holder.subtle_vertical_hover:hover .text_holder, -.portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .text_holder { - opacity: 1 -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .text_holder_inner { - padding: 5px; -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .portfolio_title { - text-transform: uppercase; - opacity: 0; - padding: 0 20px; - -ms-transform: translateY(0px); - -moz-transform: translateY(0px); - -o-transform: translateY(0px); - transform: translateY(0px); - -webkit-transform: translateY(0px); - transition: all 0.3s ease-out; - -webkit-transition: all 0.3s ease-out; -} - -.portfolio_main_holder article:hover .item_holder.subtle_vertical_hover .portfolio_title, -.portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .portfolio_title { - opacity: 1; - text-shadow: none; - -ms-transform: translateY(4px); - -moz-transform: translateY(4px); - -o-transform: translateY(4px); - transform: translateY(4px); - -webkit-transform: translateY(4px); - transition: all 0.3s ease-out; - -webkit-transition: all 0.3s ease-out; -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .text_holder .separator { - display: inline-block; - background-color: #fff; - margin-top: 20px; -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .project_category { - opacity: 0; - -ms-transform: translateY(4px); - -moz-transform: translateY(4px); - -o-transform: translateY(4px); - transform: translateY(4px); - -webkit-transform: translateY(4px); - transition: all 0.4s ease-out; - -webkit-transition: all 0.4s ease-out; - margin-bottom: 10px; -} - -.portfolio_main_holder article:hover .item_holder.subtle_vertical_hover .project_category, -.portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .project_category { - opacity: 1; - text-shadow: none; - -ms-transform: translateY(0px); - -moz-transform: translateY(0px); - -o-transform: translateY(0px); - transform: translateY(0px); - -webkit-transform: translateY(0px); -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .icons_holder { - -ms-transform: translateY(4px); - -moz-transform: translateY(4px); - -o-transform: translateY(4px); - transform: translateY(4px); - -webkit-transform: translateY(4px); - transition: all 0.4s ease-out; - -webkit-transition: all 0.4s ease-out; -} - -.portfolio_main_holder article .item_holder.subtle_vertical_hover:hover .icons_holder, -.portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .icons_holder { - -ms-transform: translateY(0); - -moz-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - -webkit-transform: translateY(0); -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .icons_holder a { - display: inline-block; - width: 40px; - height: 40px; - line-height: 40px; - background-color: #1abc9c; - border-radius: 100px; - margin: 0 3px; - color: #fff; - transition: 0.2s ease-out; - -webkit-transition: 0.2s ease-out; -} - -.portfolio_main_holder .item_holder.subtle_vertical_hover .portfolio_shader { - z-index: 3; - -webkit-transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); - transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); - opacity: 0; -} - -.portfolio_main_holder article .item_holder.subtle_vertical_hover:hover .portfolio_shader, -.portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .portfolio_shader { - opacity: 1 -} -/* #End of Subtle vertical hover - ========================================================================== */ - - - - -/* #Image subtle rotate zoom hover - ========================================================================== */ -.portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover a.portfolio_link_class { - z-index: 5; -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .image_holder { - z-index: 2; - overflow: hidden; -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .text_holder { - padding: 30px; - font-size: 14px; - width: 100%; - position: absolute; - left: 0; - height: 100%; - background-color: transparent; - top: 0; - box-sizing: border-box; - z-index: 4; - opacity: 1; -} - -.portfolio_with_hover_text .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .separator { - background-color: #fff; - opacity: 0; - -webkit-transition: opacity 0.4s ease-out; - -moz-transition: opacity 0.4s ease-out; - -ms-transition: opacity 0.4s ease-out; - -o-transition: opacity 0.4s ease-out; - transition: opacity 0.4s ease-out; -} - -.portfolio_with_hover_text .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover:hover .separator { - opacity: 1; -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .portfolio_title { - font-weight: 600; - font-size: 15px; - text-transform: uppercase; - opacity: 0; - letter-spacing: 2px; - -ms-transform: translateY(-3px); - -moz-transform: translateY(-3px); - -o-transform: translateY(-3px); - transform: translateY(-3px); - -webkit-transform: translateY(-3px); - transition: all 0.4s ease-out; - -webkit-transition: all 0.4s ease-out; -} - -.portfolio_main_holder article:hover .item_holder.image_subtle_rotate_zoom_hover .portfolio_title, -.portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .portfolio_title { - opacity: 1; - text-shadow: none; - -ms-transform: translateY(0px); - -moz-transform: translateY(0px); - -o-transform: translateY(0px); - transform: translateY(0px); - -webkit-transform: translateY(0px); -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .project_category { - opacity: 0; - text-shadow: 0px 0px 10px #fff; - -ms-transform: translateY(3px); - -moz-transform: translateY(3px); - -o-transform: translateY(3px); - transform: translateY(3px); - -webkit-transform: translateY(3px); - transition: all 0.4s ease-out; - -webkit-transition: all 0.4s ease-out; -} - -.portfolio_main_holder article:hover .item_holder.image_subtle_rotate_zoom_hover .project_category { - opacity: 1; - text-shadow: none; - -ms-transform: translateY(0px); - -moz-transform: translateY(0px); - -o-transform: translateY(0px); - transform: translateY(0px); - -webkit-transform: translateY(0px); -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .portfolio_shader { - z-index: 3; - -webkit-transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); - transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); - opacity: 0; -} - -.portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover:hover .portfolio_shader, -.portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .portfolio_shader { - opacity: 1; -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .icons_holder { - -ms-transform: translateY(3px); - -moz-transform: translateY(3px); - -o-transform: translateY(3px); - transform: translateY(3px); - -webkit-transform: translateY(3px); - transition: transform 0.4s ease-out; - -webkit-transition: transform 0.4s ease-out; - opacity: 0; -} - -.portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover:hover .icons_holder, -.portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .icons_holder { - -ms-transform: translateY(0); - -moz-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - -webkit-transform: translateY(0); - opacity: 1; -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .icons_holder a { - display: inline-block; - background-color: transparent; - border: 1px solid #fff; - width: 40px; - height: 40px; - line-height: 40px; - color: #fff; - border-radius: 100px; - margin: 0 3px; - transition: 0.2s ease-out; - -webkit-transition: 0.2s ease-out; -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .icons_holder a:hover { - background-color: #1abc9c; - color: #fff; - border-color: #1abc9c; -} - -.portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .image_holder .image img { - -webkit-transition: -webkit-transform .7s; - transition: transform .7s; -} - -.portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover:hover .image_holder .image img, -.portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .image_holder .image img { - -webkit-transform: rotate(-9deg) scale(1.15); - -ms-transform: rotate(-9deg) scale(1.15); - -moz-transform: rotate(-9deg) scale(1.15); - -o-transform: rotate(-9deg) scale(1.15); - transform: rotate(-9deg) scale(1.15); - -webkit-transition: -webkit-transform .7s; - transition: transform .7s; - backface-visibility: hidden; - -webkit-backface-visibility: hidden; -} -/* #End of image subtle rotate zoom hover - ========================================================================== */ - - - -/* #Image text zoom hover - ========================================================================== */ -.portfolio_main_holder article .item_holder.image_text_zoom_hover a.portfolio_link_class { - z-index: 5; -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .image_holder { - z-index: 2; - overflow: hidden; -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .text_holder { - padding: 30px; - font-size: 14px; - width: 100%; - height: 100%; - position: absolute; - left: 0; - background-color: transparent; - top: 0; - text-align: center; - box-sizing: border-box; - opacity: 0; - -webkit-transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - backface-visibility: hidden; - -webkit-backface-visibility: hidden; - -webkit-transform: scale(0.8); - -ms-transform: scale(0.8); - -moz-transform: scale(0.8); - -o-transform: scale(0.8); - transform: scale(0.8); - z-index: 4; -} - -.portfolio_main_holder article .item_holder.image_text_zoom_hover:hover .text_holder, -.portfolio_slider li.item:hover .item_holder.image_text_zoom_hover .text_holder { - opacity: 1; - -webkit-transform: scale(1); - -ms-transform: scale(1); - -moz-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .text_holder_outer { - display: table; - width: 100%; - height: 100%; -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .text_holder_inner { - display: table-cell; - vertical-align: middle; - text-align: center; -} - -.portfolio_with_hover_text .portfolio_main_holder .item_holder.image_text_zoom_hover .separator { - background-color: #fff; -} - -.portfolio_main_holder .project_category, .projects_masonry_holder article .project_category { - margin-bottom: 10px; -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .icons_holder a { - display: inline-block; - width: 40px; - height: 40px; - line-height: 40px; - background-color: #1abc9c; - border-radius: 50%; - margin: 0 2px; - color: #fff; - -ms-transform: translateY(0); - -moz-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - -webkit-transform: translateY(0); - transition: background-color 0.2s, transform 0.2s; - -webkit-transition: background-color 0.2s, -webkit-transform 0.2s; -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .icons_holder a:hover { - -ms-transform: translateY(-10%); - -moz-transform: translateY(-10%); - -o-transform: translateY(-10%); - transform: translateY(-10%); - -webkit-transform: translateY(-10%); -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .portfolio_shader { - z-index: 3; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - opacity: 0; -} - -.portfolio_main_holder article .item_holder.image_text_zoom_hover:hover .portfolio_shader, -.portfolio_slider li.item:hover .item_holder.image_text_zoom_hover .portfolio_shader { - opacity: 1 -} - -.portfolio_main_holder .item_holder.image_text_zoom_hover .image_holder .image { - -webkit-transition: 0.5s cubic-bezier(0.19, 1, 0.22, 1); - transition: 0.5s cubic-bezier(0.19, 1, 0.22, 1); - backface-visibility: hidden; - -webkit-backface-visibility: hidden; - display: inline-block; -} - -.portfolio_main_holder article .item_holder.image_text_zoom_hover:hover .image_holder .image, -.portfolio_slider li.item:hover .item_holder.image_text_zoom_hover .image_holder .image { - -webkit-transform: scale(1.3); - -ms-transform: scale(1.3); - -moz-transform: scale(1.3); - -o-transform: scale(1.3); - transform: scale(1.3); -} -/* #End of image text zoom hover - ========================================================================== */ - - - -/* #Thin plus only hover - ========================================================================== */ -.portfolio_main_holder.standard .item_holder.thin_plus_only { - overflow: hidden; -} - -.portfolio_main_holder .item_holder.thin_plus_only .thin_plus_only_icon { - font-weight: 100; - font-family: Raleway; - font-size: 100px; - -webkit-transition: all 0.5s 0.3s; - transition: all 0.5s 0.3s; - display: block; - color: #fff; -} - -.portfolio_main_holder .item_holder.thin_plus_only .text_holder { - width: 100%; - height: 100%; - left: 0; - margin: 0; - top: 0; - box-sizing: border-box; - z-index: 5; - -ms-transform: translate(20%, 20%); - -moz-transform: translate(20%, 20%); - -o-transform: translate(20%, 20%); - transform: translate(20%, 20%); - -webkit-transform: translate(20%, 20%); - -webkit-transition: all 0.5s 0.3s; - transition: all 0.5s 0.3s; - opacity: 0; - font-size: 0; - padding: 10%; - background-color: transparent; -} - -.portfolio_main_holder article .item_holder.thin_plus_only:hover .text_holder, -.portfolio_slider li:hover .item_holder.thin_plus_only .text_holder { - -ms-transform: translate(0, 0); - -moz-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); - -webkit-transform: translate(0, 0); - -webkit-transition: all 0.2s 0.1s; - transition: all 0.2s 0.1s; - font-size: 150px; - opacity: 1 -} - -.portfolio_main_holder .item_holder.thin_plus_only .image_holder { - z-index: 2; -} - -.portfolio_main_holder .item_holder.thin_plus_only .portfolio_shader { - z-index: 3; - transition: opacity 0.5s; - -webkit-transition: opacity 0.5s; - opacity: 0; -} - -.portfolio_main_holder article .item_holder.thin_plus_only:hover .portfolio_shader, -.portfolio_slider li.item:hover .item_holder.thin_plus_only .portfolio_shader { - opacity: 1 -} -/* #End of thin plus only hover - ========================================================================== */ - - - -/* #Slow Zoom hover - ========================================================================== */ -.portfolio_main_holder .item_holder.slow_zoom .text_holder { - width: 100%; - font-size: 18px; - left: 0; - height: 100%; - margin: 0; - top: 0; - box-sizing: border-box; - z-index: 5; - -webkit-transition: opacity 0.6s 0.3s; - transition: opacity 0.6s 0.3s; - opacity: 0; - padding: 10%; - background-color: transparent; -} - -.portfolio_main_holder article .item_holder.slow_zoom:hover .text_holder { - opacity: 1 -} - -.portfolio_with_hover_text .portfolio_main_holder article .item_holder.slow_zoom .separator { - background-color: #fff; -} - -.portfolio_main_holder .item_holder.slow_zoom .image_holder img { - -webkit-transform: scale(1.01); - -moz-transform: scale(1.01); - -o-transform: scale(1.01); - -ms-transform: scale(1.01); - transform: scale(1.01); - -webkit-transition: all 2s cubic-bezier(0.21, 1, 0.12, 1) 0s; - transition: all 2s cubic-bezier(0.23, 1, 0.12, 1) 0s; -} - -.portfolio_main_holder article .item_holder.slow_zoom:hover .image_holder img { - -webkit-transform: scale(1.1); - -moz-transform: scale(1.1); - -o-transform: scale(1.1); - -ms-transform: scale(1.1); - transform: scale(1.1); - -webkit-transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; - transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; -} - -.portfolio_main_holder .item_holder.slow_zoom .portfolio_shader { - z-index: 3; - opacity: 0; - -webkit-transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; - transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; -} - -.portfolio_main_holder article .item_holder.slow_zoom:hover .portfolio_shader, -.portfolio_slider li.item:hover .item_holder.slow_zoom .portfolio_shader { - opacity: 1; -} - -.portfolio_main_holder .item_holder.slow_zoom .icons_holder { - position: absolute; - bottom: 0; - opacity: 0; - z-index: 20; - -webkit-transition: opacity .3s, -webkit-transform .3s; - transition: opacity .3s, transform .3s; -} - -.portfolio_main_holder .item_holder.slow_zoom .icons_holder.left { - left: 0; - -webkit-transform: translate3d(-10px, -10px, 0); - -ms-transform: translate3d(-10px, 10px, 0); - -moz-transform: translate3d(-10px, 10px, 0); - -o-transform: translate3d(-10px, 10px, 0); - transform: translate3d(-10px, 10px, 0); -} - -.portfolio_main_holder .item_holder.slow_zoom .icons_holder.right { - right: 0; - -webkit-transform: translate3d(10px, 10px, 0); - -ms-transform: translate3d(10px, 10px, 0); - -moz-transform: translate3d(10px, 10px, 0); - -o-transform: translate3d(10px, 10px, 0); - transform: translate3d(10px, 10px, 0); -} - -.portfolio_main_holder .item_holder.slow_zoom .icons_holder.center { - width: 100%; - text-align: center; - -webkit-transform: translate3d(0, 10px, 0); - -ms-transform: translate3d(0, 10px, 0); - -moz-transform: translate3d(0, 10px, 0); - -o-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); -} - -.portfolio_main_holder article:hover .item_holder.slow_zoom .icons_holder, -.portfolio_slider li.item:hover .item_holder.slow_zoom .icons_holder { - opacity: 1; - display: block; - -webkit-transform: translate3d(0, 0, 0); - -ms-transform: translate3d(0, 0, 0); - -moz-transform: translate3d(0, 0, 0); - -o-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); -} - -.portfolio_main_holder .item_holder.slow_zoom .icons_holder a { - display: inline-block; - width: 40px; - height: 40px; - line-height: 40px; - text-align: center; - vertical-align: middle; - margin: 0; - font-size: 15px; - color: #fff; - background: #1abc9c; - transition: all .4s; - -webkit-transition: all .4s; -} - -.portfolio_main_holder .item_holder.slow_zoom .icons_holder a:hover { - background: #fff; - color: #000; -} - -.portfolio_main_holder .item_holder.slow_zoom .image_holder { - z-index: 2; - overflow: hidden; -} -/* #End of soom zhover - ========================================================================== */ - - - -/* #Split up hover - ========================================================================== */ -.portfolio_main_holder .item_holder.split_up .text_holder { - width: 100%; - font-size: 18px; - left: 0; - height: 100%; - margin: 0; - top: 0; - box-sizing: border-box; - z-index: 5; - -webkit-transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - opacity: 0; - padding: 10%; - background-color: transparent; -} - -.portfolio_main_holder article .item_holder.split_up:hover .text_holder { - -webkit-transition: transform 0.3s ease; - transition: transform 0.3s ease; - opacity: 1; -} - -.portfolio_main_holder .item_holder.split_up .portfolio_title { - -ms-transform: translateY(0); - -moz-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - -webkit-transform: translateY(0); - transition: 0.2s; - -webkit-transition: 0.2s; -} - -.portfolio_main_holder article .item_holder.split_up:hover .portfolio_title { - -ms-transform: translateY(-4px); - -moz-transform: translateY(-4px); - -o-transform: translateY(-4px); - transform: translateY(-4px); - -webkit-transform: translateY(-4px); -} - -.portfolio_main_holder .item_holder.split_up .project_category { - -ms-transform: translateY(-4px); - -moz-transform: translateY(-4px); - -o-transform: translateY(-4px); - transform: translateY(-4px); - -webkit-transform: translateY(-4px); - transition: 0.2s; - -webkit-transition: 0.2s; -} - -.portfolio_main_holder article:hover .item_holder.split_up .project_category { - -ms-transform: translateY(0); - -moz-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - -webkit-transform: translateY(0); -} - -.portfolio_with_hover_text .portfolio_main_holder article:hover .item_holder.split_up .separator { - background-color: #fff; -} - -.portfolio_main_holder .item_holder.split_up .image_holder { - z-index: 2; -} - -.portfolio_main_holder .item_holder.split_up .portfolio_shader, -.portfolio_slider li.item .item_holder.split_up .portfolio_shader { - height: 0; - display: block; - left: 0; - opacity: 0; - position: absolute; - top: 50%; - -webkit-transition: all 0.2s ease-out; - transition: all 0.2s ease-out; - width: 100%; - z-index: 3; -} - -.portfolio_main_holder article .item_holder.split_up:hover .portfolio_shader, -.portfolio_slider li.item:hover .item_holder.split_up .portfolio_shader { - height: 100%; - top: 0; - opacity: 1; -} -/* #End of split up hover - ========================================================================== */ - - - -/* #Cursor change hover - ========================================================================== */ -.portfolio_main_holder .item_holder.cursor_change_hover a.portfolio_link_class { - z-index: 6; - cursor: url("img/cursor_plus.cur"), crosshair; - cursor: url("img/cursor_plus.png") 22 22, crosshair; -} - -.portfolio_main_holder .cursor_img { - position: absolute; - z-index: 1000; -} - -.portfolio_main_holder .item_holder.cursor_change_hover .image_holder { - z-index: 2 -} - -.portfolio_main_holder .item_holder.cursor_change_hover .text_holder { - padding: 30px; - font-size: 14px; - width: 100%; - height: 100%; - position: absolute; - left: 0; - background-color: transparent; - top: 0; - text-align: center; - box-sizing: border-box; - opacity: 0; - -webkit-transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - backface-visibility: hidden; - -webkit-backface-visibility: hidden; - -webkit-transform: scale(0.8); - -ms-transform: scale(0.8); - -moz-transform: scale(0.8); - -o-transform: scale(0.8); - transform: scale(0.8); - z-index: 4; -} - -.portfolio_main_holder article:hover .item_holder.cursor_change_hover .text_holder, -.portfolio_slider li.item:hover .item_holder.cursor_change_hover .text_holder { - opacity: 1; - -webkit-transform: scale(1); - -ms-transform: scale(1); - -moz-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); -} - -.portfolio_with_hover_text .portfolio_main_holder .item_holder.cursor_change_hover .separator { - background-color: #fff -} - -.portfolio_main_holder .item_holder.cursor_change_hover .text_holder_outer { - display: table; - width: 100%; - height: 100%; -} - -.portfolio_main_holder .item_holder.cursor_change_hover .text_holder_inner { - display: table-cell; - vertical-align: middle; - text-align: center; -} - -.portfolio_main_holder .item_holder.cursor_change_hover .portfolio_shader { - z-index: 3; - -webkit-transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - opacity: 0; -} - -.portfolio_main_holder article .item_holder.cursor_change_hover:hover .portfolio_shader, -.portfolio_slider li.item:hover .item_holder.cursor_change_hover .portfolio_shader { - opacity: 1 -} -/* #End of cursor change hover - ========================================================================== */ - - - - -/* ========================================================================== - #End of Portfolio Hover effects styles - ========================================================================== */ - - - - - -/* ========================================================================== - Tabs shortcode start styles - ========================================================================== */ -.q_tabs{ - display: block; - visibility: hidden; -} - -.q_tabs .tabs-nav { - list-style: none outside none; - margin: 0; - overflow: hidden; - padding: 0; - display: inline-block; - position: relative; -} - -.q_tabs .tabs-nav li { - margin: 0; - overflow: hidden; - padding: 0; - position: relative; - display: inline-block; - float: left; -} - -.q_tabs .tabs-nav li a { - height: 40px; - line-height: 40px; - display: block; - margin: 0; - padding: 0 14px; - - font-size: 13px; - text-decoration: none; - font-style: normal; - color: #b4b4b4; - text-transform: uppercase; - letter-spacing: 1px; - font-weight: 700; - - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - -.q_tabs .tabs-nav li.active a { - color: #303030; -} - -.q_tabs .tabs-nav li.active a:hover, -.q_tabs .tabs-nav li a:hover { - color: #1abc9c; -} - -/* Horizontal tabs styles - ========================================================================== */ -.q_tabs.horizontal.center { - text-align: center; -} - -.q_tabs.horizontal.left { - text-align: left; -} - -.q_tabs.horizontal.right { - text-align: right; -} - -.q_tabs.horizontal .tabs-container { - padding-top: 4px; - text-align: left; -} - -.q_tabs.horizontal.right .tabs-container { - text-align: right; -} - -.q_tabs.horizontal .tabs-nav li:first-child a { - padding-left: 0; -} - -/* Vertical tabs styles - ========================================================================== */ -.q_tabs.vertical .tabs-nav { - width: 24.02957486136784%; - margin: 0; -} - -.q_tabs.vertical.right .tabs-nav { - float: right; -} - -.q_tabs.vertical.left .tabs-nav { - float: left; -} - -.q_tabs.vertical .tabs-nav li { - display: block; - width: 100%; -} - -.q_tabs.vertical .tabs-nav li a { - text-align: center; - height: auto; - line-height: normal; - padding: 13px 17px; -} - -.q_tabs.vertical .tabs-nav li.active a { - border: 2px solid #e3e3e3; - padding: 11px 14px 11px 14px; - position: relative; - z-index: 100; - - -} - -.q_tabs.vertical.left .tabs-nav li.active a { - border-right-color: #fff; - -webkit-border-top-left-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-topleft: 4px; - -moz-border-radius-bottomleft: 4px; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; -} - -.q_tabs.vertical.right .tabs-nav li.active a { - border-left-color: #fff; - -webkit-border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 4px; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -.q_tabs.vertical .tabs-container { - width: 73.68576709796673%; -} - -.q_tabs.vertical.left .tabs-container { - float: left; - text-align: left; -} - -.q_tabs.vertical.right .tabs-container { - float: right; - text-align: right; -} - -.q_tabs.vertical .tab-content { - position: relative; - z-index: 50; -} - -.q_tabs.vertical.left .tab-content { - padding-left: 17px; - border-left: 2px solid #e3e3e3; - left: -2px; -} - -.q_tabs.vertical.right .tab-content { - padding-right: 17px; - border-right: 2px solid #e3e3e3; - right: -2px; -} - -/* Boxed tabs styles - ========================================================================== */ -.q_tabs.boxed { - text-align: left; -} - -.q_tabs.boxed .tabs-nav { - display: block; -} - -.q_tabs.boxed .tabs-nav li a { - border-bottom: none; - position: relative; - z-index: 200; -} - -.q_tabs.boxed .tabs-nav li.active a { - position: relative; - z-index: 100; - line-height: 40px; - height: 40px; - padding: 0 12px; - border: 2px solid #e3e3e3; - border-bottom-color: #fff; - - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; -} - -.q_tabs.boxed .tabs-container { - overflow: hidden; - text-align: left; - padding: 19px 0 0; - border-top: 2px solid #e3e3e3; - position: relative; - top: -2px; - z-index: 50; -} - -/* ========================================================================== - Tabs shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Accordion shortcode start styles - ========================================================================== */ -.q_accordion_holder{ - position: relative; - display: block; - visibility: hidden; - margin: 0 0 30px; -} - -.q_accordion_holder.accordion.with_icon { - border-top: 1px solid #eaeaea; -} - -.q_accordion_holder.accordion .ui-accordion-header { - cursor: pointer; - position: relative; - display: block; - line-height: 2em; - min-height: 45px; - padding: 0; - margin: 0 0 5px; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); - box-sizing: border-box; -} - -.q_accordion_holder.accordion h3.ui-accordion-header { - padding-top: 3px; -} - -.q_accordion_holder.accordion h4.ui-accordion-header { - padding-top: 5px; -} - -.q_accordion_holder.accordion h5.ui-accordion-header { - font-size: 14px; - padding-top: 9px; -} - -.q_accordion_holder.accordion h6.ui-accordion-header { - padding-top: 10px; -} - -.q_accordion_holder.accordion.with_icon h3.ui-accordion-header { - padding-bottom: 3px; -} - -.q_accordion_holder.accordion.with_icon h4.ui-accordion-header { - padding-bottom: 5px; -} - -.q_accordion_holder.accordion.with_icon h5.ui-accordion-header { - padding-bottom: 9px; -} - -.q_accordion_holder.accordion.with_icon h6.ui-accordion-header { - padding-bottom: 10px; -} - -.q_accordion_holder.accordion.with_icon .ui-accordion-header{ - line-height: 3em; - min-height: 3em; - margin: 0; - border: 1px solid #eaeaea; - border-top: 0 !important; - -webkit-transition: border-bottom 0.3s ease-in-out; - -moz-transition: border-bottom 0.3s ease-in-out; - -o-transition: border-bottom 0.3s ease-in-out; - -ms-transition: border-bottom 0.3s ease-in-out; -} - -.q_accordion_holder.accordion .ui-accordion-header, -.q_accordion_holder.accordion.with_icon .ui-accordion-header { - -webkit-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - color: #303030; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 1px; - -} - -.q_accordion_holder.accordion .ui-accordion-header:hover { - color: #1abc9c; -} - -.q_accordion_holder.accordion.with_icon .ui-accordion-header:last-child { - border-bottom: 0 !important; -} - -.q_accordion_holder.accordion.with_icon .ui-accordion-header span.tab-title { - width: 72%; - line-height: 1.5625em; - margin: 0.85em 0 0.85em 20px; - display: inline-block; -} - -.q_accordion_holder.accordion.without_icon .ui-accordion-header span.tab-title{ - padding: 0 0 0 63px; - display: block; -} - -.q_accordion_holder.accordion.with_icon .ui-state-active { - border-bottom-color: transparent; - -webkit-transition: border-bottom 0.3s ease-in-out; - -moz-transition: border-bottom 0.3s ease-in-out; - -o-transition: border-bottom 0.3s ease-in-out; - -ms-transition: border-bottom 0.3s ease-in-out; -} - -.q_accordion_holder.accordion.with_icon .ui-state-active, -.q_accordion_holder.accordion .ui-state-active { - -webkit-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; - transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; -} - -.q_accordion_holder.accordion.with_icon .ui-accordion-header-active, -.q_accordion_holder.with_icon div.accordion_content { - background-color: #fbfbfb; -} - -.q_accordion_holder.accordion.with_icon .ui-accordion-header div.icon-wrapper, -.q_accordion_holder .ui-accordion-header .accordion_mark { - float: left; - line-height: 3.25em; - position: relative; - top: 0.09375em; -} - -.q_accordion_holder.accordion.without_icon .ui-accordion-header div.icon-wrapper{ - display: none !important; -} - -.q_accordion_holder.accordion.with_icon .ui-accordion-header i{ - margin: 0 0 0 15px; - font-size: 18px; - color: #1abc9c; -} - -.q_accordion_holder.accordion .ui-accordion-header .accordion_mark_icon { - display: block; - width: 41px; - height: 41px; - background-image: url(img/plus.png); - background-repeat: no-repeat; - background-position: center; -} - -.q_accordion_holder.with_icon .ui-accordion-header.ui-state-active .accordion_icon_mark{ - background-image: url(img/minus.png); -} - -.q_accordion_holder.accordion .ui-accordion-header .accordion_mark { - display: block; - width: 45px; - height: 45px; - border: 2px solid #e3e3e3; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -o-border-radius: 3px; - -ms-border-radius: 3px; - border-radius: 3px; - background-color: transparent; - transition: background-color 0.3s ease-in-out; - box-sizing: border-box; -} - -.q_accordion_holder.accordion .ui-accordion-header .accordion_mark:hover { - background-image: url('img/button-bg-px.png') !important; -} - -.q_accordion_holder.accordion .ui-accordion-header .accordion_mark.left_mark { - position: absolute; - top: 0; - left: 0; -} - -.q_accordion_holder.accordion .ui-accordion-header .accordion_mark.right_mark { - position: absolute; - right: 0.65em; - top: 0.65em; -} - -.q_accordion_holder.accordion.without_icon .ui-accordion-header .accordion_mark.right_mark, -.q_accordion_holder.accordion.with_icon .ui-accordion-header .accordion_mark.left_mark { - display: none; -} - -.q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark_icon{ - background-image: url(img/minus.png); -} - -.q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark { - background-color: #e3e3e3; - transition: background-color 0.3s ease-in-out; -} - -@media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { - .q_accordion_holder.with_icon .accordion_icon_mark, - .q_accordion_holder.accordion .ui-accordion-header .accordion_mark_icon{ - -o-background-size: 9px 9px; - -webkit-background-size: 9px 9px; - -moz-background-size: 9px 9px; - background-size: 9px 9px; - background-image: url('img/plus@1_5x.png'); - } - - .q_accordion_holder.with_icon .ui-accordion-header.ui-state-active .accordion_icon_mark, - .q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark_icon{ - -o-background-size: 9px 9px; - -webkit-background-size: 9px 9px; - -moz-background-size: 9px 9px; - background-size:9px 9px; - background-image: url('img/minus@1_5x.png'); - } -} -@media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { - .q_accordion_holder.with_icon .accordion_icon_mark, - .q_accordion_holder.accordion .ui-accordion-header .accordion_mark_icon{ - -o-background-size: 9px 9px; - -webkit-background-size:9px 9px; - -moz-background-size: 9px 9px; - background-size: 9px 9px; - background-image: url('img/plus@2x.png'); - } - - .q_accordion_holder.with_icon .ui-accordion-header.ui-state-active .accordion_icon_mark, - .q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark_icon{ - -o-background-size: 9px 9px; - -webkit-background-size: 9px 9px; - -moz-background-size: 9px 9px; - background-size: 9px 9px; - background-image: url('img/minus@2x.png'); - } -} - -.q_accordion_holder.accordion div.accordion_content{ - padding: 0 0 0 63px; - margin: 0; -} - -.q_accordion_holder.with_icon div.accordion_content { - padding: 0 0 0 50px; - border: 1px solid #eaeaea; - border-top: 0; -} - -.q_accordion_holder.accordion.with_icon div.accordion_content.no_icon{ - padding: 0 0 0 22px; -} - -.q_accordion_holder.accordion div.accordion_content_inner { - padding: 8px 0 25px; - display: block; -} - -.q_accordion_holder.with_icon div.accordion_content_inner { - padding: 10px 27px 19px 0; -} - -/* Boxed accordion and toggle styles - ========================================================================== */ -.q_accordion_holder.boxed { - -} - -.q_accordion_holder.accordion.boxed .ui-accordion-header { - text-align: center; - background-color: #e3e3e3; -} - -.q_accordion_holder.boxed .ui-accordion-header .accordion_mark { - display: none; -} - -.q_accordion_holder.boxed div.accordion_content { - padding-left: 26px; -} - -.q_accordion_holder.boxed div.accordion_content_inner { - padding-top: 20px; -} - -/* ========================================================================== - Accordion shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Highlight shortcode start styles - ========================================================================== */ -/*.highlight{ - background-color: #1abc9c; - color: #fff; - padding: 0 3px; -}*/ -/* ========================================================================== - Highlight shortcode end styles - ========================================================================== */ - -.testimonials_holder { - text-align: center; -} - -.testimonials{ - position: relative; -} - -.testimonials .testimonial_container { - overflow: hidden; - width: 100%; - background-color: transparent; - text-align: left; - margin: 0 0 16px; -} - -.testimonials_holder .flex-direction-nav { - display: block; - position: static; -} - -.testimonials_holder .flex-direction-nav li { - display: inline-block; - height: 30px; - margin-top: 37px; -} - -.testimonials_holder .flex-direction-nav li:first-child { - margin-right: 5px; -} - -.testimonials_holder .flex-direction-nav li:last-child { - margin-left: 4px; -} - -.testimonials_holder .flex-direction-nav a { - position: relative; - width: 30px; - height: 30px; - border: 2px solid #303030; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - opacity: 1; - background-color: transparent; - text-indent: -9999px; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -} - -.testimonials_holder .flex-direction-nav a:hover { - background-color: #303030; -} - -.testimonials_holder.light .flex-direction-nav a { - border-color: #fff; -} - -.testimonials_holder.light .flex-direction-nav a:hover { - background-color: #1abc9c; - border-color: #1abc9c; -} - -.testimonials_holder.light .flex-direction-nav a:before { - color: #fff; -} - -.testimonials_holder .flex-direction-nav a:before { - font-family: 'FontAwesome', sans-serif; - position: absolute; - height: 26px; - width: 26px; - line-height: 26px; - top: 0; - left: 0; - color: #000; - text-indent: 0; - font-size: 16px; -} - -.testimonials_holder .flex-direction-nav a:hover:before { - color: #fff; -} - -.testimonials_holder .flex-direction-nav a.flex-prev:before { - content: '\f104'; -} - -.testimonials_holder .flex-direction-nav a.flex-next:before { - content: '\f105'; -} - -.testimonials_holder.full_width { - background: none; -} - -.content .testimonial_content .container .container_inner { - padding:0px 0px 0px 0px; -} - -.testimonial_text_holder { - position: relative; - display: block; -} - -.testimonials .author_image_holder { - margin-left: 15px; - position: relative; -} - -.author_image_holder .image_holder { - border-radius: 3em; - border: 1px solid #eaeaea; - width: 60px; - height: 60px; - display: inline-block; - float: left; - margin:0 15px 0 0; - overflow: hidden; -} - -.testimonials .testimonial_text_inner p.testimonial_author { - font-size: 13px; - color: #303030; - margin-top: 22px; - font-weight: 500; -} - -.testimonials .testimonial_text_inner p.testimonial_author span.author_company { - color: #1abc9c; -} - -.testimonial_content_inner .testimonial_author .website{ - color:#303030; - font-weight:300; - display:block; -} - -.testimonial_content_inner .testimonial_author h4{ - color:#00a8e8; -} - -.testimonial_text_inner .testimonial_name { - display: block; -} - -.testimonial_content_inner .testimonial_author .company_position { - color: #1abc9c; -} - -.testimonials .testimonial_text_inner { - display: block; -} - -.testimonials .testimonial_text_inner p { - line-height: 1.666666666666667em; /* 35px / 13px */ - font-size: 21px; -} - -.testimonials_holder.standard .testimonials .testimonial_text_inner{ - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} - -.testimonials_holder.full_width .testimonials .testimonial_text_inner{ - border-left:none; - border-right:none; - position:relative; - text-align:center; -} - -.testimonials_holder.full_width .testimonials .testimonial_text_inner p{ - margin: 0 0 19px; -} - -.testimonial_arrow { - width: 20px; - height: 20px; - display: inline-block; - margin: 0 0 0 -10px; - z-index: 999; - position: relative; - overflow: hidden; - left: 45px; - bottom: 11px; - background-color: #fbfbfb; - border-width: 0 1px 1px 0; - border-style: solid; - border-color: #eaeaea; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); -} - -.testimonials.transparent .testimonial_text_inner { - background-color: transparent !important; - padding: 0; - border: none; -} - -.testimonial_image_holder { - text-align: center; - display: inline-block; - position: relative; - overflow: hidden; - vertical-align: middle; - margin: 0 0 50px; -} -.testimonial_image_holder img{ - vertical-align: middle; -} - -/* ========================================================================== - Blockquote shortcode start styles - ========================================================================== */ -blockquote { - position: relative; - padding: 14px 14px 14px 10px; - border-left: 4px solid transparent; -} - -blockquote h5 { - line-height: 1.5625em; - text-transform: none; - font-size: 21px; - letter-spacing: normal; - font-weight: 400; - margin: 0 !important; -} - -blockquote.with_quote_icon h5 { - padding: 0 0 0 40px; -} - -blockquote i.pull-left { - font-size: 22px; - color: #c1c0c0; - margin: 6px 0 0 !important; -} - -/* ========================================================================== - Blockquote shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Gallery shortcode styles - ========================================================================== */ - -.gallery_holder{ - display: block; - position: relative; - -} -.wpb_image_grid .gallery_holder{ - width: 100.1%; -} -.gallery_holder ul{ - list-style: none; - display: block; - width: 100%; - position: relative; - margin: 0; - padding: 0; -} - -.gallery_holder ul li{ - position: relative; - display: block; - float: left; - overflow: hidden; -} - -.gallery_holder ul li a{ - display: block; - position: relative; - -webkit-backface-visibility: hidden; -} - -.gallery_holder ul li a { - display: block; - overflow: hidden; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); -} - -.wpb_image_grid .gallery_holder ul li a { - margin-right: -1px; - margin-bottom: -1px !important; -} - -.gallery_holder ul li a img { - display: block; - width: 100%; - - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - - -webkit-transform: scale(1, 1); - -moz-transform: scale(1, 1); - -ms-transform: scale(1, 1); - -o-transform: scale(1, 1); - transform: scale(1, 1); -} - -.gallery_holder ul li.grayscale a img { - -webkit-filter: grayscale(100%); - -moz-filter: grayscale(100%); - filter: gray; - filter: grayscale(100%); - filter: url(img/desaturate.svg#grayscale); -} - -.gallery_holder ul li.grayscale:hover a img { - -webkit-filter: grayscale(0); - filter: none; -} - -.gallery_holder ul li:hover a img { - -webkit-transform: scale(1.03, 1.03); - -moz-transform: scale(1.03, 1.03); - -ms-transform: scale(1.03, 1.03); - -o-transform: scale(1.03, 1.03); - transform: scale(1.03, 1.03); -} - -.gallery_holder ul li .gallery_hover{ - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - display: inline-block; - background-color: #000; - background-color: rgba(0, 0, 0, 0.81); - visibility: visible; - opacity: 0; - filter: alpha(opacity=0); - -webkit-transition: opacity .4s; - -moz-transition: opacity .4s; - -o-transition: opacity .4s; - -ms-transition: opacity .4s; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); - -webkit-backface-visibility: hidden; - z-index: 1000; -} - -.gallery_holder ul li:hover .gallery_hover{ - opacity: 1; - filter: alpha(opacity=100); -} - -.gallery_holder ul li .gallery_hover i{ - position: absolute; - top: 50%; - left: 50%; - margin: -15px 0 0 -15px; - font-size: 30px; - color: #fff; - width: 30px; - height: 30px; - line-height:30px; - text-align: center; - display: inline-block; -} -.gallery_holder ul.v5 li, -.wpb_gallery_slides .gallery_holder ul.v5 li{ - width: 20%; - margin: 0; -} - -.gallery_holder ul.v4 li, -.wpb_gallery_slides .gallery_holder ul.v4 li{ - width: 25%; - margin: 0; -} - -.gallery_holder ul.v3 li, -.wpb_gallery_slides .gallery_holder ul.v3 li{ - width: 33.33333333333333%; - margin: 0; -} - -.gallery_holder ul.v2 li, -.wpb_gallery_slides .gallery_holder ul.v2 li{ - width: 50%; - margin: 0; -} - -/*With space gallery*/ - -.gallery_holder .gallery_with_space ul li, -.wpb_gallery_slides .gallery_holder .gallery_with_space ul li{ - margin-bottom: 2%; -} - -.gallery_holder .gallery_with_space ul li:last-child, -.wpb_gallery_slides .gallery_holder .gallery_with_space ul li:last-child{ - margin-bottom: 0; -} - -.gallery_holder ul.gallery_with_space.v2 li, -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v2 li -{ - width: 49%; - margin: 0 2% 2% 0; -} -.gallery_holder ul.gallery_with_space.v2 li:nth-child(2n), -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v2 li:nth-child(2n){ - margin-right: 0; -} - -.gallery_holder ul.gallery_with_space.v3 li, -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v3 li{ - width: 32%; - margin: 0 2% 2% 0; -} -.gallery_holder ul.gallery_with_space.v3 li:nth-child(3n), -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v3 li:nth-child(3n){ - margin-right: 0; -} -.gallery_holder ul.gallery_with_space.v4 li, -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v4 li{ - width: 23.5%; - margin: 0 2% 2% 0; -} - -.gallery_holder ul.gallery_with_space.v4 li:nth-child(4n), -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v4 li:nth-child(4n){ - margin-right: 0; -} - -.gallery_holder ul.gallery_with_space.v5 li, -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v5 li{ - width: 18.4%; - margin: 0 2% 2% 0; -} - -.gallery_holder ul.gallery_with_space.v5 li:nth-child(5n), -.wpb_gallery_slides .gallery_holder ul.gallery_with_space.v5 li:nth-child(5n){ - margin-right: 0; -} - - -/* ========================================================================== - Enf of gallery shortcode styles - ========================================================================== */ - -/* ========================================================================== - Single image shortcode styles - ========================================================================== */ -.wpb_content_element.wpb_single_image img{ - vertical-align: middle; -} - -/* ========================================================================== - Enf of single image shortcode styles - ========================================================================== */ - -/* ========================================================================== - Dropcaps shortcodes styles - ========================================================================== */ -.q_dropcap{ - position: relative; - display: inline-block; - float: left; - height: 48px; - width: 48px; - line-height: 48px; - font-size: 23px; - color: #1abc9c; - text-align: center; - margin: 5px 20px 0 0; - border: 1px solid transparent; -} - -.q_dropcap.circle, -.q_dropcap.square{ - margin: 5px 20px 0 0; - font-size: 22px; - background-color: #1abc9c; - border: 1px solid transparent; - color: #fff; - font-weight: 300; -} - -.q_dropcap.normal{ - font-weight: 700; - position: relative; - left: 8px; -} - -.q_dropcap.circle { - -webkit-border-radius: 2em; - -moz-border-radius: 2em; - -ms-border-radius: 2em; - -o-border-radius: 2em; - border-radius: 2em; -} - -.q_dropcap.square { - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} - -/* ========================================================================== - Message box shortcode styles - ========================================================================== */ -.q_message { - position: relative; - padding: 26px 30px; - color: #fff; - background-color: #1abc9c; - -} - -.q_message .q_message_inner{ - position: relative; -} - -.q_message.with_icon .q_message_icon_holder{ - float:left; - padding:0 27px 0 0; -} - -.q_message.with_icon .q_message_icon{ - display: table; - height: 100%; -} - -.q_message.with_icon .q_message_icon_inner { - display: table-cell; - height: 100%; - vertical-align: middle; -} - -.q_message.with_icon > i { - line-height: 1em; -} - -.q_message.with_icon img { - float: left; -} - -.q_message a.close { - position: absolute; - top: -19px; - right: -23px; - line-height: 13px; - color: #fff; -} - -.q_message a.close i { - width: 14px; - height: 14px; - display: inline-block; - background-repeat: no-repeat; - background-position: center; -} - -.q_message .message_text { - display: table; - height: 100%; - font-weight: 700; - font-size: 18px; - text-transform: uppercase; - letter-spacing: 1px; -} - -.q_message .message_text_holder { - padding: 0px 20px 0px 0px; -} - -.q_message .message_text_inner { - display: table-cell; - height: 100%; - vertical-align: middle; -} - -.q_message.with_icon .message_text_holder { - padding: 0px 20px 0px 0px; -} - -/* ========================================================================== - Pricing table shorcode styles - ========================================================================== */ -.q_price_table { - position: relative; - width: 100%; - padding: 0; - color: #fff; - border-top: 1px solid #ebebeb; - - margin-left: 2.5%; - float: left; -} - -.qode_pricing_tables.two_columns .q_price_table { - width: 48.75%; -} - -.qode_pricing_tables.three_columns .q_price_table { - width: 31.666666666666668%; -} - -.qode_pricing_tables.four_columns .q_price_table { - width: 23.125%; -} - -.qode_pricing_tables .q_price_table:first-child { - margin-left: 0; -} - -.q_price_table .price_table_inner { - - background-color: #262626; - position: relative; -} - -.q_price_table.active .active_text { - position: absolute; - top: 0; - left: 0; - width: 100%; - text-align: center; - background-color: #1abc9c; - font-size: 13px; - line-height: 31px; -} - -.q_price_table.active .price_table_inner > ul { - padding: 31px 0 0; - margin: -31px 0; -} - -.price_table_inner ul { - list-style: none outside none; - margin: 0; - padding-left: 0 !important; -} - -.price_table_inner ul li { - text-align: center; - margin: 0; - padding: 2px 20px 13px; -} - -.price_table_inner ul li.pricing_table_content { - padding: 20px 27px 10px; -} - -.price_table_inner ul li.pricing_table_content li { - font-size: 13px; -} - -.price_table_inner ul li.pricing_table_content li:last-child { - border-bottom: none; -} - -.price_table_inner ul li.prices { - padding-top: 0; - padding-bottom: 3px; -} - -.price_table_inner ul li.table_title { - padding: 25px 25px 3px; -} - -.price_table_inner ul li.table_title .title_content { - color: #fff; - font-weight: 700; - font-size: 17px; -} - -.price_in_table { - text-align: center; -} - -.price_in_table .value { - font-size: 20px; - font-weight: 600; - vertical-align: top; - position: relative; - top: 17px; -} - -.price_in_table .price { - font-size: 83px; - line-height: 1em; - padding: 0 3px; - font-weight: 200; - vertical-align: middle; -} - -.price_in_table .mark { - vertical-align: bottom; - position: relative; - font-size: 16px; - font-weight: 600; - text-transform: uppercase; - top: 10px; -} - -.price_table_inner .price_button{ - padding: 0 0 32px; -} - -.price_button .qbutton{ - margin:0 7px; -} -/* ========================================================================== - Icon with text shortcode start styles - ========================================================================== */ -.q_icon_with_title{ - display: block; - position: relative; -} - -.q_icon_with_title .icon_holder { - display: inline-block; - position: relative; - z-index: 2; -} - -.q_icon_with_title:not(.right) .icon_holder { - float: left; -} - -.q_icon_with_title.right .icon_holder { - float: right; -} - -.q_icon_with_title .icon_text_holder .icon_title { - display: block; - margin: 0 0 1.08em; - font-weight: 600; -} - -.q_icon_with_title.large .icon_text_holder .icon_title { - margin-bottom: 0.35em; -} - -.q_icon_with_title .icon_with_title_link { - display: inline-block; - margin: 13px 0 0; - color: #1abc9c; -} - -.q_icon_with_title .icon_with_title_link:hover { - color: #303030; -} - -.q_icon_with_title .icon_holder.q_icon_animation, -.box_holder_icon_inner.q_icon_animation{ - -webkit-transform: scale(0); - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - transform: scale(0); - -webkit-transition: all 0.4s ease; - -moz-transition: all 0.4s ease; - -o-transition: all 0.4s ease; - transition: all 0.4s ease; - -webkit-backface-visibility: hidden; -} - -.q_icon_with_title .icon_holder.q_icon_animation.q_show_animation, -.box_holder_icon_inner.q_icon_animation.q_show_animation{ - -webkit-transform: scale(1.0); - -moz-transform: scale(1.0); - -ms-transform: scale(1.0); - -o-transform: scale(1.0); - transform: scale(1.0); -} - -.q_icon_with_title .icon_holder .fa-stack, -.box_holder_icon_inner .fa-stack, -.q_font_awsome_icon_square, -.q_font_awsome_icon_stack i.fa-stack-base { - border: 2px solid #c0c0c0; - - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -ms-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - - -webkit-backface-visibility: hidden; - -webkit-box-sizing: initial; - -moz-box-sizing: initial; - box-sizing: initial; -} -.q_font_awsome_icon_stack i.fa-stack-base{ - border:none; -} -.q_icon_with_title .icon_text_holder{ - position: relative; -} - -.q_icon_with_title span.fa-stack .qode_iwt_icon_element, -.q_box_holder.with_icon span.fa-stack .qode_iwt_icon_element { - font-size: 0.7em; - color: #c0c0c0; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -ms-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s ease-in-out; -} - -.q_icon_with_title.circle span.fa-stack .qode_iwt_icon_element { - font-size: 0.9em; -} - -.q_icon_with_title span.fa-stack.custom-font .qode_iwt_icon_element { - font-size: 0.7em; -} - -.q_icon_with_title .icon_text_inner{ - padding: 0 0 18px; -} - -.q_icon_with_title .icon_title_holder { - display: table; - width: 100%; - height: 100%; - margin:0 0 12px; -} - -.q_icon_with_title .icon_title_holder .icon_holder{ - display: table-cell; - text-align: center; - height: 100%; - vertical-align: middle; - float:none; - padding:0 15px 0 0; - box-sizing: content-box; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - -} - -.q_icon_with_title .icon_title_holder .icon_holder > span { - position: relative; - top: 2px; -} - -.q_icon_with_title .icon_text_holder .icon_title_holder .icon_title { - display: table-cell; - margin: 0 0 0; - vertical-align: middle; - width: 100%; -} - -.q_font_awsome_icon_square .qode_icon_element { - color: #fff; -} - -.q_font_awsome_icon_stack .qode_icon_element { - color: #fff; -} - -.qode_icon_shortcode.fa-stack a { - display: block; - width: 100%; - height: 100%; -} - -.qode_icon_shortcode.fa-stack .qode_icon_element { - display: block; - line-height: inherit; -} - -.touch .no_animation_on_touch .q_icon_animation{ - -webkit-transform: scale(1.0); - -moz-transform: scale(1.0); - -ms-transform: scale(1.0); - -o-transform: scale(1.0); - transform: scale(1.0); -} - -/* Icon center styles - ========================================================================== */ -/** - * Styles when icon is in center. Can be in a box or not - */ - -.q_icon_with_title.center{ - text-align: center; - } - -.q_icon_with_title.center.center .icon_holder{ - float: none; - display: block; - margin: 0 0 20px; -} - -.q_icon_with_title.custom_icon_image.center .icon_holder{ - margin: 0 0 13px; -} - -.q_icon_with_title.center .icon_holder{ - width: 100% !important; -} - -.q_icon_with_title.center .icon_holder .font_awsome_icon i { - color: #7b7b7b; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - - -.q_icon_with_title.center .icon_holder .font_awsome_icon i:hover { - color: #1abc9c; -} - -/* End of icon center styles - ========================================================================== */ - -/* Generic icon styles - ========================================================================== */ - -.q_icon_with_title.boxed .icon_holder .fa-stack, -.q_font_awsome_icon_square { - background-color: #1abc9c; - border-radius: 4px; - text-align: center; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - -webkit-backface-visibility: hidden; -} - -.q_box_holder.with_icon .box_holder_icon_inner .fa-stack i.fa-stack-base{ - color: #1abc9c; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - -webkit-backface-visibility: hidden; -} - -.q_icon_with_title.square .icon_holder .fa-stack, -.box_holder_icon_inner.square .fa-stack -{ - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.q_font_awsome_icon_square{ - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.q_icon_with_title.square .icon_holder .fa-stack:hover, -.box_holder_icon_inner.square .fa-stack:hover, -.box_holder_icon_inner.circle .fa-stack:hover, -.circle .icon_holder .fa-stack:hover{ - background-color: #1abc9c; - border-color: transparent !important; -} - -.q_font_awsome_icon_stack .fa-circle, -.q_icon_with_title.boxed .icon_holder .fa-stack { - color: #1abc9c; - -webkit-transition: color 0.4s ease-in-out; - -moz-transition: color 0.4s ease-in-out; - -o-transition: color 0.4s ease-in-out; - transition: color 0.4s ease-in-out; -} - -.q_icon_with_title.circle .icon_holder .fa-stack:hover i.fa-circle, -.q_font_awsome_icon_stack:hover .fa-circle, -.q_box_holder.with_icon .box_holder_icon_inner .fa-stack:hover i.fa-stack-base { - color: #f3f3f3 !important; -} - -.q_icon_with_title.boxed .icon_holder .fa-stack { - -webkit-transition: background-color 0.2s ease-in-out; - -moz-transition: background-color 0.2s ease-in-out; - -o-transition: background-color 0.2s ease-in-out; - transition: background-color 0.2s ease-in-out; -} - -.q_icon_with_title.circle .icon_holder .fa-stack:hover .qode_iwt_icon_element, -.q_icon_with_title.square .icon_holder .fa-stack:hover .qode_iwt_icon_element, -.q_font_awsome_icon_stack:hover i:last-child, -.q_icon_with_title.boxed .icon_holder .fa-stack:hover i, -.q_box_holder.with_icon span.fa-stack:hover i:last-child, -.q_icon_with_title.square .icon_holder .fa-stack:hover i, -.box_holder_icon_inner.square:hover i, -.q_font_awsome_icon_square:hover i { - color: #fff; -} - -.q_box_holder.with_icon .tiny span.fa-stack i:last-child { - top: 1px; -} - - -.q_icon_with_title.with_border_line .icon_text_inner{ - border-bottom: 1px solid #fbfbfb; -} - -.q_icon_with_title.tiny .icon_text_holder { - padding: 0 0 0 44px; -} - -.q_icon_with_title.small .icon_text_holder{ - padding: 0 0 0 46px; -} - -.q_icon_with_title.left_from_title .icon_text_holder{ - padding: 0; -} - -.q_icon_with_title.medium .icon_holder, -.q_icon_with_title.tiny.square .icon_holder, -.q_icon_with_title.small.square .icon_holder{ - text-align: center; -} - -.q_icon_with_title.tiny.square .icon_text_holder, -.q_icon_with_title.medium .icon_text_holder { - padding: 0 0 0 56px; -} - -.q_icon_with_title.large .icon_text_holder{ - padding: 0 0 0 65px; -} - -.q_icon_with_title.large .icon_holder{ - text-align: center; -} - -.q_icon_with_title.very_large .icon_text_holder{ - padding: 0 0 0 84px; -} - -.q_icon_with_title.tiny.boxed .icon_text_holder, -.q_icon_with_title.tiny.circle .icon_text_holder, -.q_icon_with_title.tiny.custom_icon_image .icon_text_holder{ - padding: 0 0 0 55px; -} - -.q_icon_with_title.small.square .icon_text_holder, -.q_icon_with_title.small.boxed .icon_text_holder, -.q_icon_with_title.small.circle .icon_text_holder, -.q_icon_with_title.small.custom_icon_image .icon_text_holder{ - padding: 0 0 0 72px; -} - -.q_icon_with_title.medium.circle .icon_text_holder { - padding: 0 0 0 119px; -} - -.q_icon_with_title.medium.boxed .icon_text_holder, -.q_icon_with_title.medium.custom_icon_image .icon_text_holder, -.q_icon_with_title.medium.square .icon_text_holder{ - padding: 0 0 0 95px; -} - -.q_icon_with_title.large.boxed .icon_text_holder, -.q_icon_with_title.large.circle .icon_text_holder, -.q_icon_with_title.large.custom_icon_image .icon_text_holder, -.q_icon_with_title.large.square .icon_text_holder{ - padding: 0 0 0 122px; -} - -.q_icon_with_title.very_large.boxed .icon_text_holder, -.q_icon_with_title.very_large.circle .icon_text_holder, -.q_icon_with_title.very_large.custom_icon_image .icon_text_holder, -.q_icon_with_title.very_large.square .icon_text_holder{ - padding: 0 0 0 150px; -} - -.q_icon_with_title.left_from_title .icon_text_holder{ - padding: 0 0 0 0px !important; -} - -.q_icon_with_title.right .icon_text_holder { - padding-left: 0 !important; - text-align: right; -} - -.q_icon_with_title.tiny.circle.right .icon_text_holder, -.q_icon_with_title.tiny.custom_icon_image.right .icon_text_holder{ - padding: 0 55px 0 0; -} - -.q_icon_with_title.small.square.right .icon_text_holder, -.q_icon_with_title.small.circle.right .icon_text_holder, -.q_icon_with_title.small.custom_icon_image.right .icon_text_holder { - padding: 0 72px 0 0; -} - -.q_icon_with_title.medium.circle.right .icon_text_holder { - padding: 0 119px 0 0; -} - -.q_icon_with_title.medium.custom_icon_image.right .icon_text_holder, -.q_icon_with_title.medium.square.right .icon_text_holder{ - padding: 0 95px 0 0; -} - -.q_icon_with_title.large.circle.right .icon_text_holder, -.q_icon_with_title.large.custom_icon_image.right .icon_text_holder, -.q_icon_with_title.large.square.right .icon_text_holder{ - padding: 0 122px 0 0; -} - -.q_icon_with_title.very_large.circle.right .icon_text_holder, -.q_icon_with_title.very_large.custom_icon_image.right .icon_text_holder, -.q_icon_with_title.very_large.square.right .icon_text_holder{ - padding: 0 150px 0 0; -} - -.q_icon_with_title.tiny.square.right .icon_text_holder { - padding: 0 56px 0 0; -} - -.q_icon_with_title.left_from_title .icon_text_holder .icon_holder{ - width: auto !important; -} - -.q_icon_with_title.left_from_title.custom_icon_image.tiny .icon_text_holder .icon_holder{ - width: 35px !important; -} - -.q_icon_with_title.left_from_title.custom_icon_image.small .icon_text_holder .icon_holder{ - width: 52px !important; -} - -.q_icon_with_title.left_from_title.custom_icon_image.medium .icon_text_holder .icon_holder{ - width: 78px !important; -} - -.q_icon_with_title.left_from_title.custom_icon_image.large .icon_text_holder .icon_holder{ - width: 104px !important; -} - -.q_icon_with_title.left_from_title.custom_icon_image.very_large .icon_text_holder .icon_holder{ - width: 130px !important; -} - -.q_icon_with_title.tiny.center .icon_text_holder, -.q_icon_with_title.small.center .icon_text_holder, -.q_icon_with_title.medium.center .icon_text_holder, -.q_icon_with_title.large.center .icon_text_holder, -.q_icon_with_title.very_large.center .icon_text_holder, -.q_icon_with_title.tiny.boxed.center .icon_text_holder, -.q_icon_with_title.tiny.circle.center .icon_text_holder, -.q_icon_with_title.small.boxed.center .icon_text_holder, -.q_icon_with_title.small.circle.center .icon_text_holder, -.q_icon_with_title.medium.boxed.center .icon_text_holder, -.q_icon_with_title.medium.circle.center .icon_text_holder, -.q_icon_with_title.large.boxed.center .icon_text_holder, -.q_icon_with_title.large.circle.center .icon_text_holder, -.q_icon_with_title.very_large.boxed.center .icon_text_holder, -.q_icon_with_title.very_large.circle.center .icon_text_holder, -.q_icon_with_title.tiny.custom_icon_image.center .icon_text_holder, -.q_icon_with_title.small.custom_icon_image.center .icon_text_holder, -.q_icon_with_title.medium.custom_icon_image.center .icon_text_holder, -.q_icon_with_title.large.custom_icon_image.center .icon_text_holder, -.q_icon_with_title.very_large.custom_icon_image.center .icon_text_holder{ - padding: 0; -} - -.q_icon_with_title.left_from_title .icon_holder{ - display: block; -} - -.q_icon_with_title.tiny .icon_holder img, -.q_icon_with_title.left_from_title.tiny .icon_holder, -.q_icon_with_title.left_from_title.small.normal_icon .icon_holder{ - width: 35px; -} - -.q_icon_with_title.small .icon_holder img, -.q_icon_with_title.left_from_title.small .icon_holder, -.q_icon_with_title.left_from_title.large.normal_icon .icon_holder{ - width: 52px; -} - -.q_icon_with_title.medium .icon_holder img, -.q_icon_with_title.left_from_title.medium .icon_holder, -.q_icon_with_title.left_from_title.very_large.normal_icon .icon_holder{ - width: 78px; -} - -.q_icon_with_title.large .icon_holder img, -.q_icon_with_title.left_from_title.large .icon_holder{ - width: 104px; -} - -.q_icon_with_title.very_large .icon_holder img, -.q_icon_with_title.left_from_title.very_large .icon_holder{ - width: 130px; -} - -.q_icon_with_title.left_from_title.tiny.normal_icon .icon_holder{ - width: 25px; -} - -.q_icon_with_title.left_from_title.medium.normal_icon .icon_holder{ - width: 45px; -} - -/* End of generic icon center styles - ========================================================================== */ - -.q_icon_with_title.circle .qode_iwt_icon_holder .qode_iwt_icon_element, -.q_icon_with_title.square .qode_iwt_icon_holder .qode_iwt_icon_element { - display: block; - height: 100%; - line-height: inherit; - text-align: center; -} - -/* ========================================================================== - End if icon with text shortcode styles - ========================================================================== */ - -/* ========================================================================== - Icon start shortcode - ========================================================================== */ - -.q_font_awsome_icon { - display: inline-block; -} - -.q_font_awsome_icon i, -.q_font_awsome_icon span { - color: #1abc9c; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; - -webkit-backface-visibility: hidden; -} - -.q_font_awsome_icon i:hover, -.q_font_awsome_icon span:hover { - color: #1abc9c; -} - -.q_font_awsome_icon.pull-center{ - display: block; - text-align: center; -} - -.q_font_awsome_icon_square.pull-center, -.q_font_awsome_icon_stack.pull-center{ - display: block; - margin: 0 auto !important; -} - -.q_font_awsome_icon.q_icon_animation, -.q_font_awsome_icon_square.q_icon_animation, -.q_font_awsome_icon_stack.q_icon_animation{ - -webkit-transform: scale(0); - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - transform: scale(0); - -webkit-transition: -webkit-transform 0.4s ease; - -moz-transition: -moz-transform 0.4s ease; - -o-transition: -o-transform 0.4s ease; - -ms-transition: -ms-transform 0.4s ease; - transition: transform 0.4s ease; - -webkit-backface-visibility: hidden; -} - -.q_font_awsome_icon.q_icon_animation.q_show_animation, -.q_font_awsome_icon_square.q_icon_animation.q_show_animation, -.q_font_awsome_icon_stack.q_icon_animation.q_show_animation{ - -webkit-transform: scale(1.0); - -moz-transform: scale(1.0); - -ms-transform: scale(1.0); - -o-transform: scale(1.0); - transform: scale(1.0); -} - -#back_to_top span, -.q_social_icon_holder .fa-stack, -.q_icon_with_title.square .icon_holder .fa-stack, -.box_holder_icon_inner.square .fa-stack { - text-align: center; -} - -/* ========================================================================== - Icon end shortcode - ========================================================================== */ - -.drop_down .wide .second ul li div.flexslider li:nth-child(4n+1){ - clear: none; -} - -.drop_down .wide .second ul li .flexslider ul { - padding:0; - border:none; -} - -.drop_down .wide .second ul li ul.flex-direction-nav a{ - position:absolute; - top:0; - border:none; - margin:0px 0 0 0; -} - -.drop_down .wide .second ul li ul.flex-direction-nav{ - position:absolute; - top:45px; - left:0px; - overflow:visible; - width: 100%; -} - -.drop_down .wide .second ul li div.flexslider{ - margin: 0; -} - -.drop_down .wide .second ul li .flexslider.widget_flexslider ul.flex-direction-nav li{ - width: 100%; -} - -.flexslider.widget_flexslider h3, -.drop_down .wide .second ul li ul li .flexslider.widget_flexslider h3, -.drop_down .wide .second ul li ul li .flexslider.widget_flexslider h3 a{ - color: #fff; - font-size: 15px; - font-weight: 400; - line-height: 22px; - padding: 10px 0 2px !important; -} - -.flexslider.widget_flexslider ul li h3 a, -.drop_down .wide .second .inner ul li.flexslider.widget_flexslider ul li h3 a{ - color: #000; - font-size: 18px; - font-weight: 300; - line-height: 22px; -} - -.flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev, -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev{ - background-color: #000; - background-color: rgba(0, 0, 0, 0.4); - width: 40px; - height: 40px; - line-height: 40px; -} - -.drop_down .second .flexslider.widget_flexslider ul.flex-direction-nav i { - display:inline; -} - -.drop_down .wide.icons .second .flexslider.widget_flexslider ul.flex-direction-nav i { - width:auto; - float:none; - height:auto; - color: #fff; -} - -.flexslider.widget_flexslider ul.flex-direction-nav a.flex-next, -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-next{ - background-color: #000; - background-color: rgba(0, 0, 0, 0.4); - width: 40px; - height: 40px; - line-height: 40px; -} - -.flexslider.widget_flexslider ul.flex-direction-nav a.flex-next:hover, -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-next:hover, -.flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev:hover, -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev:hover{ - background-color:#000; -} - -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider .menu_recent_post_text { - padding: 10px 0; -} - -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider .menu_recent_post_text a{ - display: inline; - padding: 0; -} - -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider .menu_recent_post_text a:hover{ - color:#fff; -} - -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider a, -.drop_down .wide .second ul li .flexslider.widget_flexslider a{ - padding: 0; - margin: 0; -} - -.drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider a i, -.drop_down .wide .second ul li .flexslider.widget_flexslider a i{ - font-size: 20px; -} - -ul.flickr_widget{ - display: inline-block; - position: relative; - padding:0; -} - -ul.flickr_widget li{ - float: left; - margin: 0px 5px 5px 0px; -} - -ul.flickr_widget li:nth-child(3n){ - margin: 0 0 5px; -} - -ul.flickr_widget li a img{ - float: left; -} - -.menu_recent_post_text{ - display: block; -} - -.menu_recent_post_text a{ - display: inline-block !important; - color: #fff !important; -} - -/* ========================================================================== - Icon progress bar shortcode start styles - ========================================================================== */ -.q_progress_bars_icons{ - display: block; - position: relative; - opacity: 0; - filter: alpha(opacity=0); -} - -.q_progress_bars_icons_inner{ - position: relative; - width: 100%; -} - -.q_progress_bars_icons_inner .bar{ - position: relative; - float: left; - margin: 0px 10px 10px 0px; -} - -.q_progress_bars_icons_inner.normal .bar{ - margin: 0 0 10px; -} - -.q_progress_bars_icons_inner.tiny .bar{ - height: 39px; - width: 39px; -} - -.q_progress_bars_icons_inner.small .bar{ - width: 56px; - height: 56px; -} - -.q_progress_bars_icons_inner.medium .bar{ - width: 83px; - height: 83px; -} - -.q_progress_bars_icons_inner.large .bar{ - width: 109px; - height: 109px; -} - -.q_progress_bars_icons_inner.very_large .bar{ - width: 135px; - height: 135px; -} - -.q_progress_bars_icons_inner .bar .bar_noactive, -.q_progress_bars_icons_inner .bar .bar_active{ - display: inline-block; - position: absolute; - top: 0px; - left: 0px; - overflow: hidden; - z-index: 50; -} - -.q_progress_bars_icons_inner .bar.active .bar_noactive { - z-index: 100; -} - -.q_progress_bars_icons_inner.square .bar .bar_noactive, -.q_progress_bars_icons_inner.square .bar .bar_active{ - border: 1px solid #d7d7d7; - - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} - -.q_progress_bars_icons_inner.circle .bar .bar_noactive, -.q_progress_bars_icons_inner.circle .bar .bar_active { - border: 1px solid #d7d7d7; - - -webkit-border-radius: 2em; - -moz-border-radius: 2em; - -ms-border-radius: 2em; - -o-border-radius: 2em; - border-radius: 2em; -} - -.q_progress_bars_icons_inner.square .bar.active .bar_noactive, -.q_progress_bars_icons_inner.square .bar.active .bar_active, -.q_progress_bars_icons_inner.circle .bar.active .bar_noactive, -.q_progress_bars_icons_inner.circle .bar.active .bar_active { - border: 1px solid #1abc9c; -} - -.q_progress_bars_icons_inner.square .bar.active i, -.q_progress_bars_icons_inner.circle .bar.active i, -.q_progress_bars_icons_inner.normal .bar.active i, -.q_progress_bars_icons_inner .bar.active i.fa-circle{ - color: #1abc9c; -} - -.q_progress_bars_icons_inner.square .bar i, -.q_progress_bars_icons_inner.circle .bar i, -.q_progress_bars_icons_inner.normal .bar i, -.q_progress_bars_icons_inner .bar i.fa-circle{ - color: #d7d7d7; -} - -/* ========================================================================== - Icon progress bar shortcode end styles - ========================================================================== */ - -.more_facts_outer{ - position: relative; - display: block; - height: 0; - overflow: hidden; -} - -.more_facts_inner_holder{ - position: relative; - display: inline-block; - width: 100%; - vertical-align: middle; -} - -.more_facts_inner{ - display: inline-block; - width: 100%; - padding: 70px 0 0; - position: relative; -} -.more_facts_holder{ - background-color: #f6f6f6; -} -.more_facts_button { - display: block; - position: relative; - margin: 0; - padding: 39px 0 15px; - color: #303030; - font-size: 19px; - line-height: 22px; - cursor: pointer; - z-index: 90; - -} -.more_facts_button:hover{ - color: #1abc9c; -} -.more_facts_button .more_facts_button_text, -.more_facts_button .more_facts_button_arrow{ - display: block; -} -.more_facts_button .more_facts_button_text{ - display: block; - font-size: 17px; - font-weight: 600; - letter-spacing: 1px; - text-transform: uppercase; - padding: 0px 0 5px; -} -.more_facts_button .more_facts_button_arrow{ - -webkit-transition: -webkit-transform 300ms ease-in-out; - -moz-transition: -moz-transform 300ms ease-in-out; - -ms-transition: -ms-transform 300ms ease-in-out; - -o-transition: -o-transform 300ms ease-in-out; - transition: transform 300ms ease-in-out; - -} -.more_facts_button .more_facts_button_arrow.rotate_arrow { - -webkit-transform: rotate(-180deg); - -moz-transform: rotate(-180deg); - -ms-transform: rotate(-180deg); - -o-transform: rotate(-180deg); - transform: rotate(-180deg); -} -.more_facts_button_holder{ - display: block; - position: relative; -} - -.more_facts_button_holder.left{ - text-align: left; -} - -.more_facts_button_holder.center{ - text-align: center; -} - -.more_facts_button_holder.right{ - text-align: right; -} - - -/* ========================================================================== - Oblique section styles - ========================================================================== */ - -.angled-section { - position: absolute; - z-index: 20; - display:block; -} - -.angled-section polygon{ - fill: #f6f6f6; -} - -.angled-section.svg-top { - top: -85px; -} - -.angled-section.svg-bottom { - bottom: -85px; -} - -.angled-section.svg-footer-bottom { - bottom: 0; -} - -.angled-section.svg-title-bottom { - bottom: 0; -} - -/* ========================================================================== - End of Oblique section styles - ========================================================================== */ - - -.ordered ul, .ordered ol { - counter-reset: li; - display: block; - list-style-type: decimal; - background-position: left center; - background-repeat: no-repeat; - margin: 0 0 30px; - padding: 0 0 0 20px; -} - -.ordered ol li { - margin: 0px 0px 21px; - padding: 0 0 0 4px; - color: #303030; -} - -/* ========================================================================== - Unordered list shortcode styles - ========================================================================== */ -.q_list.normal ul > li { - font-weight: 400 !important; -} - -.q_list.light ul > li { - font-weight: 300 !important; -} - -.q_list.bold ul > li { - font-weight: 600 !important; -} - -.q_list.circle ul, -.q_list.number ul{ - display: block; - list-style-type: none; - margin: 0; - padding: 0; -} - -.q_list.number ul{ - counter-reset: li; -} - -.q_list.number.circle_number li { - padding-left: 43px; - margin-bottom: 22px; -} - -.q_list.circle ul>li, -.q_list.number ul>li{ - position: relative; - font-weight: 400; - margin: 0 0 22px; - padding: 0 0 0 22px; - color: #303030; -} - -.q_list.circle ul>li:before { - position: absolute; - left: 0; - width: 7px; - height: 7px; - top: 9px; - background-color: #ababab; - display: block; - content: ''; - border-radius: 25px; -} - -.q_list.number ul>li:before{ - height: 20px; - width: 20px; - line-height: 20px; - display: inline-block; - position: absolute; - left: 0; - top: 1px; - padding: 0; - color: #1abc9c; - text-align: center; - content: counter(li, decimal-leading-zero); - counter-increment: li; - font-weight: 500; -} - -.q_list.number.circle_number ul>li:before { - color: #fff; - background-color: #1abc9c; - border-radius: 2em; - height: 31px; - width: 31px; - line-height: 31px; - top: -3px; -} - - -.q_list.circle.animate_list ul li, -.q_list.number.animate_list ul li{ - opacity: 0; - filter: alpha(opacity = 0); - top: -40px; -} - -.touch .no_animation_on_touch .q_list.circle.animate_list ul li, -.touch .no_animation_on_touch .q_list.number.animate_list ul li{ - opacity: 1; - filter: alpha(opacity = 100); - top: 0px; -} - -/* ========================================================================== - Social icon shortcode styles - ========================================================================== */ -.q_social_icon_holder{ - display: inline-block; - position: relative; -} -.q_social_icon_holder.normal_social{ - margin: 0 6px; -} -header .header_top .q_social_icon_holder { - float: left; - margin: 0; - width: 32px; -} - -.q_social_icon_holder .simple_social { - color: #bcbcbc; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; -} - -.q_social_icon_holder span.simple_social { - display: inline-block; -} - -.q_social_icon_holder:hover .simple_social{ - color: #1abc9c; -} - -header .header_top .q_social_icon_holder a { - display: block; -} - -header .header_top .q_social_icon_holder:last-child { - border-right: 0; -} - -header .header_top .q_social_icon_holder .simple_social.fa-lg{ - font-size: 13px; -} - -.q_social_icon_holder .fa-stack { - background-color: #e3e3e3; - border: 0px solid #f0f0f0; - margin: 0.2307692307692308em; - - -webkit-transition: all 0.3s ease-out; - -moz-transition: all 0.3s ease-out; - -o-transition: all 0.3s ease-out; - transition: all 0.3s ease-out; - -} - -.q_social_icon_holder.circle_social .fa-stack { - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; -} - -.q_social_icon_holder .fa-stack -.header_top .q_social_icon_holder .fa-stack { - background: transparent; - border: 0; - padding: 0; - margin: 0; - box-shadow: none; - border-radius: 0; - font-size: 13px; -} - -.header_top .q_social_icon_holder .fa-stack:hover i, -.header_top .q_social_icon_holder .fa-stack:hover span { - color: #fff; -} - -.q_social_icon_holder .fa-stack i, -.q_social_icon_holder .fa-stack span { - color: #b9b9b9; - -webkit-transition: color 0.3s ease-out; - -moz-transition: color 0.3s ease-out; - -o-transition: color 0.3s ease-out; - transition: color 0.3s ease-out; -} - -.header_top .q_social_icon_holder .fa-stack i, -.header_top .q_social_icon_holder .fa-stack span{ - color: #7b7b7b; -} - -.q_social_icon_holder.circle_social .fa-stack:hover, -.q_social_icon_holder.square_social .fa-stack:hover { - background-color: #1abc9c; - border-color: transparent; -} - -.q_social_icon_holder.circle_social .fa-stack:hover i, -.q_social_icon_holder.circle_social .fa-stack:hover span, -.q_social_icon_holder.square_social .fa-stack:hover i, -.q_social_icon_holder.square_social .fa-stack:hover span { - color: #fff; -} - -.q_social_icon_holder .fa-stack i.fa-circle, -.q_social_icon_holder .fa-stack span.fa-circle { - color: #fbfbfb; -} - -.q_social_icon_holder .fa-stack.fa-2x { - width:36px; - height:36px; - line-height:36px; -} - -.q_social_icon_holder .fa-stack i:last-child, -.q_social_icon_holder .fa-stack span { - font-size: 0.7692307692307692em; - display: block; - line-height: inherit; -} - -.q_social_icon_holder .fa-stack.fa-lg i:last-child, -.q_social_icon_holder .fa-stack.fa-lg span { - font-size: 1em; -} - -/* ========================================================================== - Social share shortcode styles - ========================================================================== */ -.social_share_holder{ - position: relative; - display: inline-block; -} - -.social_share_holder:hover .social_share_title { - cursor: pointer; -} - -.social_share_holder:hover .social_share_dropdown{ - visibility: visible; -} - -.social_share_title{ - display: inline-block; -} - -.social_share_dropdown{ - display: block; - left: 3px; - margin: 0px 0 0; - padding: 10px 0 0 0; - position: absolute; - top: 100%; - width: 35px; - visibility: hidden; - z-index: 950; -} - -.social_share_dropdown .inner_arrow { - display: block; - position: absolute; - top: -6px; - left: 8px; - width: 0; - height: 0; - border-color: transparent transparent #323232 transparent; - border-style: solid; - border-width: 9px; - z-index: 999; -} - - - -.social_share_dropdown ul { - list-style: none; - position: relative; - display: block; - background-color: #323232; - z-index: 990; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; - padding: 4px 0px !important; - width:35px; -} - -.page_share{ - position: relative; -} - -.social_share_dropdown ul li{ - display: block; - position: relative; - text-align: center; -} - -.social_share_dropdown ul li.share_title { - display: block; - text-align: center; - color: #fff; - background-color: #1abc9c; - padding: 10px 20px; -} - -.social_share_dropdown ul li a { - display: block; - height: 20px; - line-height: 20px; - padding: 5px 0; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - margin: 0 !important; -} - -.social_share_dropdown ul li:last-child a { - border-bottom: 0; -} - -.social_share_dropdown ul li i{ - font-size: 17px; - width: 22px; - height: 22px; - line-height: 22px; - color: #fff; - text-align: center; -} -.social_share_dropdown ul li img{ - width: 22px; - float: left; - margin: 0 13px 0 0; -} - -.social_share_dropdown ul li :hover i{ - color: #1abc9c; -} - -/* ========================================================================== - Social share list shortcode styles - ========================================================================== */ -.social_share_list_holder ul { - list-style: none; - display: inline-block; -} - -.social_share_list_holder ul li { - display: inline; - margin-right: 10px; -} - -.social_share_list_holder ul li i { - color: #bcbcbc; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - -.social_share_list_holder ul li i:hover { - color: #1abc9c; -} - -/* ========================================================================== - Empty Space - ========================================================================== */ -.vc_empty_space_inner .empty_space_image{ - display: block; - height: 100%; -} - - -/* ========================================================================== - Masonry Gallery - ========================================================================== */ - -.grid-sizer { - width: 25%; -} - -.masonry_gallery_holder{ - margin: 0 -10px; - opacity: 0; -} - -.masonry_gallery_holder .masonry_gallery_item { - box-sizing: border-box; - padding: 10px; - z-index: 1; -} - -.masonry_gallery_holder .masonry_gallery_item.parallax_item { - z-index: 0; -} - -/*one column shortcode*/ -.masonry_gallery_holder.one_column .masonry_gallery_item.square_big, -.masonry_gallery_holder.one_column .masonry_gallery_item.square_small, -.masonry_gallery_holder.one_column .masonry_gallery_item.rectangle_landscape, -.masonry_gallery_holder.one_column .masonry_gallery_item.rectangle_portrait, -.masonry_gallery_holder.one_column .grid-sizer{ - width: 100%; -} -/*end of one column shortcode*/ - -/*two columns shortcode*/ - -.masonry_gallery_holder.two_columns .masonry_gallery_item.square_small, -.masonry_gallery_holder.two_columns .masonry_gallery_item.rectangle_portrait, -.masonry_gallery_holder.two_columns .grid-sizer{ - width: 50%; -} - -.masonry_gallery_holder.two_columns .masonry_gallery_item.square_big, -.masonry_gallery_holder.two_columns .masonry_gallery_item.rectangle_landscape{ - width: 100%; -} - -/*end of two columns shortcode*/ - -/*three columns shortcode*/ - -.masonry_gallery_holder.three_columns .masonry_gallery_item.square_small, -.masonry_gallery_holder.three_columns .masonry_gallery_item.rectangle_portrait, -.masonry_gallery_holder.three_columns .grid-sizer{ - width: 33.33333333%; -} - -.masonry_gallery_holder.three_columns .masonry_gallery_item.square_big, -.masonry_gallery_holder.three_columns .masonry_gallery_item.rectangle_landscape{ - width: 66.66666666%; -} - -/*end of three columns shortcode*/ - -.masonry_gallery_item.square_small { - width: 25%; -} -.masonry_gallery_item.square_big { - width: 50%; -} -.masonry_gallery_item.rectangle_landscape { - width: 50%; -} - -.masonry_gallery_item.rectangle_portrait { - width: 25%; -} - -.masonry_gallery_holder .masonry_gallery_item .masonry_gallery_image_holder{ - height: 100%; - width: 100%; - position: relative; - overflow: hidden; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); - -ms-transform: translateZ(0px); - -o-transform: translateZ(0px); - transform: translateZ(0px); -} - -.masonry_gallery_holder .masonry_gallery_item.rectangle_landscape .masonry_gallery_image_holder img{ - max-height: inherit; -} - -.masonry_gallery_holder .masonry_gallery_item.rectangle_portrait .masonry_gallery_image_holder img{ - max-width: inherit; - width: auto; -} - -.masonry_gallery_item img { - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - vertical-align: middle; - max-height: 100%; -} - -.masonry_gallery_item .masonry_gallery_item_outer { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - text-align: center; - box-sizing: border-box; - padding: 10px; -} - -.masonry_gallery_item .masonry_gallery_item_inner { - position: relative; - height: 100%; -} - -.masonry_gallery_item_inner .masonry_gallery_item_content { - position: absolute; - top: 50%; - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); - -moz-transform: translateY(-50%); - -o-transform: translateY(-50%); - transform: translateY(-50%); - width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding:0 10% 0 10%; -} - -.masonry_gallery_item.with_icon .masonry_gallery_item_inner, -.masonry_gallery_item.with_button .masonry_gallery_item_inner{ - background-color: rgba(0,0,0,0.8); -} - -.masonry_gallery_item.standard .masonry_gallery_item_inner{ - opacity: 0; - background-color: rgba(0,0,0,0.8); - -webkit-transition: opacity 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out; -} - -.masonry_gallery_item.standard:hover .masonry_gallery_item_inner{ - opacity: 1; -} - -.masonry_gallery_item_content h3, -.masonry_gallery_item_icon { - color: #fff; -} - -.masonry_gallery_item .masonry_gallery_item_icon { - color: #fff; - margin: 0 0 10px; -} - -.masonry_gallery_item_content h3 { - text-transform: uppercase; - padding: 0 0 20px 0; -} - -.masonry_gallery_item .masonry_gallery_item_button{ - margin: 20px 0 0 0; -} - -.masonry_gallery_item_content .masonry_gallery_item_text { - color: #818181; -} - -/* ========================================================================== - Blog slider - ========================================================================== */ -.blog_slider, .blog_slides .image_holder { - position: relative; - display: block; - -webkit-backface-visibility: hidden; -} - -.blog_slider .blog_slides { - opacity: 0; -} - -.blog_slider .image{ - position: relative; - display: block; - overflow: hidden; - width: 100%; - -moz-transform: translateZ(0px); - -webkit-transform: translateZ(0px); -} - -.blog_slider .blog_slides>li{ - background-color: transparent; - position: relative; - margin: 0; - float: left; -} - -.blog_slider_holder .item_holder { - position: relative; - overflow: hidden; -} - -.blog_slider { - margin: 0; - width: 100.2%; - position: relative; - zoom: 1; -} - -.blog_slider .blog_slides img { - width: 100%; - display: block; - -webkit-transition: -webkit-transform 0.15s ease-out; - -moz-transition: -moz-transform 0.15s ease-out; - -ms-transition: -ms-transform 0.15s ease-out; - -o-transition: -o-transform 0.15s ease-out; - transition: transform 0.15s ease-out; -} - -.blog_slider .flex-viewport { - max-height: 2000px; - -webkit-transition: all 1s ease; - -moz-transition: all 1s ease; - transition: all 1s ease; - direction: ltr; -} - -.blog_slider .blog_slides { - margin: 0; - padding: 0; - list-style: none; - zoom: 1; -} - -.blog_slider .flex-direction-nav{ - *height: 0; -} - -.blog_text_holder{ - position:absolute; - width:100%; - height:100%; - opacity: 0; - -webkit-transition: all 1s ease; - -moz-transition: all 1s ease; - transition: all 1s ease; - background-color: rgba(21, 21, 21, 0.78); -} -.blog_slides .blog_text_holder_inner{ - color: #fff; -} -.blog_text_holder_outer{ - display: table; - table-layout: fixed; - width: 100%; - height: 100%; - text-align: center; -} - -.blog_text_holder_inner{ - display: table-cell; - vertical-align: middle; -} - -.blog_slides .item:hover .blog_text_holder { - opacity: 0.8; - z-index: 20; -} - -.blog_slides .blog_text_holder_inner .blog_slider_title a, .blog_slider_date_holder, -.blog_slides .blog_text_holder_inner .blog_slider_categories a, -.blog_slider .blog_slider_post_comments{ - color: #fff; - -webkit-transition: color 0.15s ease; - -moz-transition: color 0.15s ease; - transition: color 0.15s ease; -} - -.blog_slider .blog_slider_date_holder, -.blog_slider .blog_slider_categories{ - display: inline-block; -} - -.blog_slider .caroufredsel-next, -.full_width .section_inner .blog_slider .caroufredsel-next{ - right: 20px; -} - - -body.boxed .blog_slider .caroufredsel-next, -body.boxed .full_width .section_inner .blog_slider .caroufredsel-next{ - right: 0; -} - -.blog_slider .caroufredsel-prev, -.full_width .section_inner .blog_slider .caroufredsel-prev{ - left: 20px; -} - - -body.boxed .blog_slider .caroufredsel-prev, -body.boxed .full_width .section_inner .blog_slider .caroufredsel-prev{ - left: 0; -} -.blog_slider .caroufredsel-next, -.full_width .section_inner .blog_slider .caroufredsel-next, -.blog_slider .caroufredsel-prev, -.full_width .section_inner .blog_slider .caroufredsel-prev{ - border-radius:50%; -} - -.blog_slider .flex-container a:active, .blog_slider .flexslider a:active, -.blog_slider .flex-container a:focus, .blog_slider .flexslider a:focus{ - outline: 0; -} - -/*Blog Carousel Info in Bottom Always*/ - -.blog_text_holder.info_bottom{ - height: auto; - width: auto; - bottom: 0; - margin: 0 10px 10px; - opacity: 1; - z-index: 20; -} - -.blog_slides .item:hover .blog_text_holder.info_bottom{ - opacity: 1; -} - -.blog_text_holder.info_bottom .blog_text_holder_outer{ - padding: 15px 0; -} - -.blog_text_holder.info_bottom .blog_text_date_holder{ - display: table-cell; - vertical-align: middle; - width: 60px; - border-right: 1px solid #ebebeb; -} - -.blog_text_holder.info_bottom .blog_text_holder_inner{ - padding: 0 10px; - text-align: left; -} - -.blog_text_holder.info_bottom .blog_slider_date_holder span{ - display: block; -} - -/*Blog slider simple*/ - -.blog_slider_holder .blog_slider.simple_slider .blog_text_wrapper{ - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; -} - - -.blog_slider.simple_slider .blog_slides .blog_text_holder_inner{ - color: #303030; -} - -.blog_slider_holder .blog_slider.simple_slider .blog_text_holder_inner2{ - position: relative; - width: 50%; - margin: 0 auto; - padding : 8%; - border: 1px solid #fafafa; - background-color: rgba(255,255,255,0.6); - box-sizing: border-box; - -webkit-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; - -moz-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; - -ms-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; - -o-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; - transition: background-color 0.15s ease-out, border-color 0.15s ease-out; -} - -.blog_slider_simple_info{ - text-align: center; -} - -.blog_slider .blog_slider_simple_title{ - margin-bottom: 20px; -} - -.blog_slider .blog_slider_simple_info a, -.blog_slider .blog_slider_simple_title a{ - -webkit-transition: color 0.15s ease; - -moz-transition: color 0.15s ease; - transition: color 0.15s ease; -} - -.blog_slider_simple_holder .read_more_wrapper{ - margin-top: 20px; -} - -.blog_slider_simple_info .post_info_item{ - display: inline-block; - padding: 0 5px; -} - -.blog_slider_simple_info .post_info_item:not(:first-child):before{ - content: '/'; - position: relative; - left: -5px; -} - -.blog_slider_simple_info .post_info_item.date span{ - -webkit-transition: color 0.15s ease-out; - -moz-transition: color 0.15s ease-out; - -ms-transition: color 0.15s ease-out; - -o-transition: color 0.15s ease-out; - transition: color 0.15s ease-out; -} - -/* ========================================================================== - Latest posts styles - ========================================================================== */ -.latest_post_holder{ - display: inline-block; - width: 100%; -} - -.latest_post_holder.date_in_box .latest_post { - padding-left:85px; -} - -.latest_post_holder.minimal .latest_post{ - border-bottom: none; - padding-bottom: 0px; -} - -.latest_post_holder li:last-child .latest_post { - border-bottom: none; -} - -.latest_post_holder .latest_post_date { - float: left; - margin-right: 25px; - width: 59px; - border-radius: 4px; - text-align: center; - margin-top: 5px; -} - -.latest_post_holder .latest_post_date .post_publish_day { - font-size: 22px; - color: #fff; - height: 39px; - line-height: 39px; - background-color: #1abc9c; -} - -.latest_post_holder .latest_post_date .post_publish_month { - border: 1px solid #eaeaea; - background-color: #f4f4f4; - color: #303030; - font-size: 12px; - -webkit-border-bottom-left-radius: 2px; - -webkit-border-bottom-right-radius: 2px; - -moz-border-radius-bottomleft: 2px; - -moz-border-radius-bottomright: 2px; - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - height: 18px; - line-height: 18px; -} - -.latest_post_holder > ul{ - list-style: none; - display: inline-block; - width: 100%; - position: relative; - margin: 0; - padding:0; -} - -.latest_post_holder > ul > li { - display: block; - position: relative; - padding-top: 15px; -} - -.latest_post_holder.minimal > ul > li { - padding-top: 11px; -} - -.latest_post_holder.image_in_box .latest_post_holder > ul > li{ - padding-top: 15px; -} - -.latest_post_holder > ul > li:first-child{ - padding-top: 0; -} - -.latest_post_holder.boxes > ul, -.latest_post_holder.dividers > ul{ - clear: both; -} - -.latest_post_holder.boxes > ul > li, -.latest_post_holder.dividers > ul > li{ - padding: 0; - float: left; - border: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - -o-box-sizing: border-box; - margin: 0 2% 0 0; - background-color:#fff; -} - -.latest_post_holder.boxes.two_columns > ul > li, -.latest_post_holder.dividers.two_columns > ul > li{ - width: 49%; -} - -.latest_post_holder.boxes.three_columns > ul > li, -.latest_post_holder.dividers.three_columns > ul > li{ - width: 32%; -} - -.latest_post_holder.boxes.four_columns > ul > li, -.latest_post_holder.dividers.four_columns > ul > li{ - width: 23.5%; -} - -.latest_post_holder.boxes.two_columns > ul > li:nth-child(2n), -.latest_post_holder.boxes.three_columns > ul > li:nth-child(3n), -.latest_post_holder.boxes.four_columns > ul > li:nth-child(4n), -.latest_post_holder.dividers.two_columns > ul > li:nth-child(2n), -.latest_post_holder.dividers.three_columns > ul > li:nth-child(3n), -.latest_post_holder.dividers.four_columns > ul > li:nth-child(4n){ - margin-right: 0; -} - -.latest_post_holder.boxes:not(.one_row) > ul > li, -.latest_post_holder.dividers:not(.one_row) > ul > li{ - margin-bottom: 25px; -} - -.latest_post_holder.boxes > ul > li .latest_post{ - padding: 19px 20px 10px; - border-top: 0; -} - -.latest_post_holder.boxes > ul > li .latest_post p.excerpt{ - margin: 10px 0 9px; -} - -.latest_post_holder.boxes > ul > li .latest_post .post_infos > a, -.latest_post_holder.boxes > ul > li .latest_post .post_infos > span{ - display: inline-block; -} - -.latest_post_holder.boxes > ul > li .latest_post .latest-vert-separator{ - margin-left: 3px; -} - -.latest_post_holder.boxes .boxes_image { - overflow: hidden; -} - -.latest_post_holder.boxes .boxes_image a { - display: block; - - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); - - -webkit-transition: -webkit-transform 0.3s ease-in-out; - -moz-transition: -moz-transform 0.3s ease-in-out; - -ms-transition: -ms-transform 0.3s ease-in-out; - -o-transition: -o-transform 0.3s ease-in-out; - transition: transform 0.3s ease-in-out; - -webkit-backface-visibility: hidden; -} - -.latest_post_holder.boxes .boxes_image a img { - vertical-align: top; -} - -.latest_post_holder.boxes .boxes_image a:hover { - -webkit-transform: scale(1.1); - -moz-transform: scale(1.1); - -ms-transform: scale(1.1); - -o-transform: scale(1.1); - transform: scale(1.1); -} - -.latest_post_holder.dividers .latest_post_date, -.latest_post_holder.dividers .latest_post_text_inner{ - display: table-cell; -} - -.latest_post_holder.dividers .latest_post_title{ - margin-bottom: 20px -} - -.latest_post_holder.dividers .latest_post_inner{ - margin: 35px 0 !important; -} - -.latest_post_holder.dividers .boxes_image img{ - display: inline-block; - vertical-align: middle; -} - -.latest_post_holder.dividers .latest_post_date{ - margin: 0 15px 0 0; - border-right: 1px solid #ebebeb; - width: 50px; -} - -.latest_post_holder.dividers .latest_post_date .latest_post_day{ - font-size: 15px; - font-weight: 600; - color: #303030; -} - -.latest_post_holder.dividers .post_infos{ - margin-top:30px; - padding-top: 20px; - border-top: 1px solid #ebebeb; -} - -.latest_post_holder.dividers .post_infos > a:not(:last-child):after, -.latest_post_holder.dividers .post_infos > span:not(:last-child) > a:after{ - content: '/'; - margin: 0 3px; -} - -.latest_post_holder.dividers .latest_post_text_inner .post_infos a{ - margin-right: 0; -} - - -.latest_post_holder > ul > li .date_hour_holder i{ - margin-right: 8px; -} - -.latest_post, -.latest_post > a, -.latest_post a img{ - display: block; - position: relative; -} - -.latest_post_image { - width: 95px; - float: left; -} - -.latest_post_image img{ - width:100%; - float: left; -} - -.latest_post_text{ - display: block; - width: auto; -} - -.latest_post_holder.image_in_box .latest_post_text{ - padding:0 0 0 116px; -} - -.latest_post_holder.minimal .latest_post_inner{ - margin: 0 0 0px !important; -} - -.latest_post_inner{ - margin: 0 0 10px !important; -} - - -.latest_post_holder.image_in_box .latest_post_text_inner { - display: table-cell; - vertical-align: middle; -} - -.latest_post_holder.image_in_box .latest_post_inner { - display: table; - width: 100%; - margin: 0 0 0 !important; -} - -.latest_post_inner .post_infos{ - display: block; - font-weight: 500; -} - -.latest_post_inner .post_infos a{ - color:#303030; -} - -.latest_post_inner .post_infos a{ - margin: 0 7px 0 0; -} - -.latest_post_inner .post_infos a.post_comments{ - margin: 0; -} - -.latest_post_inner .post_infos a:hover{ - color:#1abc9c; -} - -.latest_post_holder.minimal .latest_post_inner .post_infos{ - margin:0 0 3px 0; -} - -.latest_post_holder.image_in_box .latest_post_text .latest_post_title { - margin:-3px 0 2px 0; -} -.latest_post_holder.image_in_box .latest_post_text .excerpt { - margin:0 0 8px 0; -} -.latest_post_holder .post_infos .dots{ - padding: 0 7px 0 7px; -} -.latest_post_holder .post_infos .dots i{ - font-size: 3px; - vertical-align: middle; -} - -/* ========================================================================== - Blog Masonry Shortcode - ========================================================================== */ - -.q_masonry_blog { - margin-bottom: 50px; - transition: none !important; - overflow: visible !important; - opacity: 0; - filter: alpha(opacity=0); -} - -.q_masonry_blog article, -.full_width .grid_section .q_masonry_blog article -{ - width: 31.2%; - margin: 0 0 20px; - padding: 0; - text-align: left; - vertical-align: top; - z-index: 100; - border: 0; - background-color: #fff; - float: left; - display: block; -} -.full_width .q_masonry_blog article{ - width: 18.9%; - margin-left: 0.5%; - margin-right: 0.5%; -} -.q_masonry_blog article.format-link:hover, -.q_masonry_blog article.format-quote:hover{ - background-color: #1abc9c; -} -.q_masonry_blog article.format-link .q_masonry_blog_post_title, -.q_masonry_blog article.format-quote .q_masonry_blog_post_title{ - padding: 0 0 0 60px; -} -.q_masonry_blog article.format-quote .q_masonry_blog_post_text i.qoute_mark, -.q_masonry_blog article.format-link .q_masonry_blog_post_text i.link_mark { - margin: 7px 0 0; - color: #c0c0c0; - font-size: 36px; -} -.q_masonry_blog article.format-quote .q_masonry_blog_post_text p, -.q_masonry_blog article.format-link .q_masonry_blog_post_text p{ - font-size: 21px; - line-height: 35px; - color: #303030; -} -.q_masonry_blog article.format-link:hover .q_masonry_blog_post_info, -.q_masonry_blog article.format-link:hover .q_masonry_blog_post_info a, -.q_masonry_blog article.format-quote:hover .q_masonry_blog_post_info, -.q_masonry_blog article.format-quote:hover .q_masonry_blog_post_info a, -.q_masonry_blog article.format-quote:hover .q_masonry_blog_post_text .quote_author, -.q_masonry_blog article.format-quote:hover .q_masonry_blog_post_text i.qoute_mark, -.q_masonry_blog article.format-link:hover .q_masonry_blog_post_text i.link_mark, -.q_masonry_blog article.format-quote:hover .q_masonry_blog_post_text p a, -.q_masonry_blog article.format-link:hover .q_masonry_blog_post_text p a { - color: #fff; -} -.two_columns_75_25 .q_masonry_blog article, -.two_columns_66_33 .q_masonry_blog article, -.two_columns_33_66 .q_masonry_blog article, -.two_columns_25_75 .q_masonry_blog article{ - width:48%; -} - -.q_masonry_blog article:hover{ - z-index: 200; -} - -.q_masonry_blog article .q_masonry_blog_post_image{ - margin: 0; - width: auto; -} -.q_masonry_blog article .q_masonry_blog_post_image img{ - vertical-align: middle; -} -.q_masonry_blog article .q_masonry_blog_post_info{ - margin:15px 0 0 0; - color:#303030; -} -.q_masonry_blog article .q_masonry_blog_post_info a{ - color: #bebebe; -} -.q_masonry_blog article .q_masonry_blog_post_info a:hover{ - color: #1abc9c; -} -.q_masonry_blog article .quote_author { - font-family: inherit; - font-weight: 400; - display: block; - font-size: 21px; - line-height: 35px; - color: #c0c0c0; -} -.q_masonry_blog article.format-link .q_masonry_blog_post_info, -.q_masonry_blog article.format-quote .q_masonry_blog_post_info{ - margin: 0 0 20px; -} -.q_masonry_blog article .q_masonry_blog_post_text{ - padding: 20px 15px 20px 15px; -} - -.q_masonry_blog article h5{ - margin:0 0 10px; -} -.q_masonry_blog article .mejs-controls div.mejs-horizontal-volume-slider{ - margin: 0 10px 0 0; -} -.q_masonry_blog article .flexslider{ - margin-bottom: 0; -} - - -/* ========================================================================== - Blog - ========================================================================== */ - -.blog_holder article{ - display: inline-block; - width: 100%; - margin: 0 0 60px; -} -.blog_holder.masonry article, -.blog_holder.masonry_full_width article -{ - display: block; - float: left; -} -.blog_holder.blog_large_image_simple article{ - margin: 0 0 23px; -} -.blog_holder.blog_single article{ - margin: 0 0 0px; -} -.blog_holder.blog_small_image article{ - margin: 0 0 32px; -} -.single-post .blog_single p { - margin-bottom: 22px; -} - -.single-post .blog_single p:last-child { - margin-bottom: 0; -} -.blog_single.blog_holder article .post_text .post_text_inner{ - padding-left:0; - padding-right:0; - padding-bottom:0; - background-color:transparent; -} -.blog_single.blog_holder article.format-link .post_text .post_text_inner, -.blog_single.blog_holder article.format-quote .post_text .post_text_inner{ - padding: 23px 23px 35px 23px; - background-color: #fff; - margin:0 0 30px 0; -} -.blog_holder article .post_content_holder{ - width: 100%; -} - -.blog_holder article .post_image, -.blog_holder article .post_image > a, -.blog_holder article .post_image img{ - position: relative; - width: 100%; - display: block; -} -.blog_holder article .post_text .post_text_inner{ - padding:23px 23px 35px 23px; - background-color:#fff; -} -.blog_holder.blog_large_image_simple article .post_text .post_text_inner{ - background-color: transparent; - padding-left: 195px; - padding-right: 195px; - padding-top: 45px; - padding-bottom: 45px; - text-align: center; -} -.blog_holder.masonry article .post_text .post_text_inner, -.blog_holder.masonry_full_width article .post_text .post_text_inner{ - padding:17px 15px 18px 15px; - background-color:#fff; -} -.blog_large_image_simple .minimalist_date{ - padding-bottom: 9px; - color:#1abc9c; -} -.blog_large_image_simple .separator.small{ - margin-top: 22px; -} -.blog_holder article .post_text h5 { - margin:0 0 10px; -} -.blog_holder article .post_text h2 .date{ - color:#bebebe; -} -.blog_holder article .post_info { - display:inline-block; - width:100%; - margin:0 0 18px; - color:#bebebe; - font-weight:500; -} -.blog_holder article .post_info a{ - color:#bebebe; -} -.blog_holder article .post_info a:hover{ - color:#1abc9c; -} -.blog_holder article.format-quote .post_info, -.blog_holder article.format-link .post_info { - margin:0 0 15px; -} - -.blog_holder article .post_info .dots{ - padding: 0 7px 0 4px; -} -.blog_holder article .post_info .dots i{ - font-size: 3px; - vertical-align: middle; -} -.blog_holder article .post_more{ - margin:30px 0 0; -} -.blog_holder article .video .mobile-video-image { - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - display: none; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; - z-index: 10; -} - -.blog_holder article .video{ - position: relative; -} - -.blog_holder article .video .video-wrap { - overflow: hidden; - position: relative; - width: 100%; - z-index: 10; -} - -.blog_holder article .video .video-wrap .mejs-poster { - background-size: cover!important; - -moz-background-size: cover!important; - -webkit-background-size: cover!important; - -o-background-size: cover!important; - width: 100% !important; - height: 100% !important; -} - -.blog_holder article .video .video-wrap .mejs-container { - background-color: transparent!important; - background-image: none!important; - height: 100% !important; - width: 100% !important; - overflow: hidden; -} - -.blog_holder article .video .video-wrap .mejs-mediaelement{ - background: none !important; - border: 0px !important; -} - -.blog_holder article .video .video-wrap .mejs-container .mejs-poster img { - max-width: none!important; - width: 100%!important; -} - -.blog_holder article .mejs-container .mejs-controls{ - visibility: visible !important; -} - -.blog_holder article .mejs-controls .mejs-volume-button .mejs-volume-slider{ - display: none !important; -} - -.blog_holder article .post_image .mejs-poster img{ - display: none !important; -} - -.blog_holder article.format-gallery .flexslider{ - margin: 0px; - overflow: hidden; -} - -.portfolio_single .flexslider{ - overflow: hidden; -} - -.blog_holder.blog_small_image article .post_image, -.blog_holder.blog_small_image article .post_text{ - width:50%; - float:left; - margin:0; -} - -.blog_holder.blog_small_image article .post_text .post_text_inner{ - padding: 23px 23px 23px 23px; -} - -.grid2 .blog_holder.blog_small_image article .post_comments { - margin-left: 0; -} -.blog_holder article .post_description{ - margin: 2px 0 10px; -} - -/*Blog Large Image With Dividers*/ -.blog_holder.blog_large_image_with_dividers .post_text_holder{ - display: table; - width: 100%; - height: 100%; -} - -.blog_holder.blog_large_image_with_dividers article .post_text .post_text_inner{ - padding: 35px 0; -} - -.blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1{ - display: table-cell; - vertical-align: top; - text-align: center; - width: 70px; -} - -.blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column2{ - display: table-cell; - padding: 0 35px 0 20px; -} - -.blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column2 > h2{ - margin-bottom: 20px; -} - -.blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1 .date{ - padding: 0 20px; - border-right: 1px solid #ebebeb; -} - -.blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1 .date > span{ - display: block; -} - -.blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1 .date_day{ - font-size: 21px; - font-weight: 600; - color: #303030; - padding-bottom: 5px; -} - -.blog_holder.blog_large_image_with_dividers article .post_info{ - display: table; - width: 100%; - border-top: 1px solid #ebebeb; - padding-top: 15px; - color: #303030; - margin-bottom: 0; -} - -.blog_holder.blog_large_image_with_dividers article:not(.format-quote):not(.format-link) .post_info{ - margin-top: 30px; -} - -.blog_holder.blog_large_image_with_dividers article .post_info .post_info_left{ - display: table-cell; -} - -.blog_holder.blog_large_image_with_dividers article .post_info .post_info_right{ - display: table-cell; - text-align: right; -} - -.blog_holder.blog_large_image_with_dividers article .post_info a{ - display: inline-block; - color: #303030; -} - -.blog_holder.blog_large_image_with_dividers article .post_info a:hover{ - color: #1abc9c; -} - -.blog_holder.blog_large_image_with_dividers article .post_info .post_info_right > a:not(:first-child):before, -.blog_holder.blog_large_image_with_dividers article .post_info .post_info_right > div:not(:first-child):before{ - content: '/ '; -} - -.blog_holder.blog_large_image_with_dividers article.format-quote .post_text .post_title, -.blog_holder.blog_large_image_with_dividers article.format-link .post_text .post_title{ - padding: 0; -} - -.blog_holder.blog_large_image_with_dividers article.format-link .post_text .post_title a{ - color: #1abc9c; - text-decoration: underline; -} - -.blog_holder.blog_large_image_with_dividers article.format-link .post_text:hover .post_title a{ - color: #fff; -} - -.blog_holder.blog_large_image_with_dividers article.format-quote .post_text .quote_author{ - margin-top:30px; - color: #1abc9c; -} - -.blog_holder.blog_large_image_with_dividers article.format-quote .post_info, -.blog_holder.blog_large_image_with_dividers article.format-link .post_info{ - margin-top: 20px; -} - -.blog_holder.blog_large_image_with_dividers article.format-quote .post_text span.qoute_mark, -.blog_holder.blog_large_image_with_dividers article.format-link .post_text span.link_mark{ - font-size: 28px; - padding: 0 18px; - border-right: 1px solid #ebebeb; - color: #303030; -} - - - -.latest_post_inner .post_comments i { - font-size:16px; - color: #adadad; - padding:0 8px 0 0; -} - -.latest_post_inner .post_comments:hover i { - color:#1abc9c; -} - - -.blog_holder article .post_info .post_info_left a.post_author_avatar { - display:inline-block; - float:left; - padding:0 10px 0 0; -} - -.blog_holder article .post_info .post_info_left a.post_author { - display:inline-block; - line-height:64px; - float:left; -} - -.post_author_avatar img{ - border-radius:60px; - border:2px solid #eaeaea; -} - -.blog_holder.masonry article .post_description, -.blog_holder.masonry_full_width article .post_description{ - margin:0 0 4px; -} - -.blog_holder article .post_description a:hover, -.blog_holder article .post_description .post_comments:hover{ - color: #1abc9c; -} - -.blog_like{ - display: inline-block; -} - -.blog_like a{ - display: block; - line-height: 14px; -} - -.blog_like a i{ - color: #adadad; - font-size: 16px; -} - -.blog_holder.masonry article .blog_like a i, -.blog_holder.masonry_full_width article .blog_like a i, -.blog_holder.blog_single article .blog_like a i, -.blog_holder.blog_large_image article .blog_like a i{ - display: inline-block; -} - -.blog_like a:hover i, -.blog_like a.liked i, -.blog_like a:hover span{ - color: #1abc9c; -} - -.blog_like span{ - padding: 0 0 0 4px; -} - -.blog_holder.masonry article .blog_like span, -.blog_holder.masonry_full_width article .blog_like span, -.blog_holder.blog_single article .blog_like span, -.blog_holder.blog_large_image article .blog_like span{ - display: inline-block; - padding:0 0 0 5px; -} - -.blog_holder article .post_info .qbutton.dark { - text-transform: none; -} - -.blog_share{ - display: inline-block; -} - -.blog_holder article.format-quote .post_text i.qoute_mark, -.blog_holder article.format-link .post_text i.link_mark{ - margin: 7px 0 0; - color:#c0c0c0; - font-size: 36px; -} - -.blog_large_image_simple.blog_holder article.format-quote .post_text i.qoute_mark, -.blog_large_image_simple.blog_holder article.format-link .post_text i.link_mark{ - margin: 20px 0; - float: none; -} - -.blog_holder article.format-quote .post_text .post_title, -.blog_holder article.format-link .post_text .post_title{ - padding: 0 0 0 60px; -} -.blog_large_image_simple.blog_holder article.format-quote .post_text .post_title, -.blog_large_image_simple.blog_holder article.format-link .post_text .post_title{ - padding: 0 0 0 0px; -} -.blog_holder article.format-quote .post_text .post_title p, -.blog_holder article.format-link .post_text .post_title p{ - font-size:21px; - line-height:35px; - color:#303030; -} - -.blog_holder article.format-quote .post_text .quote_author{ - font-family: inherit; - font-weight: 400; - display:block; - font-size: 21px; - line-height: 35px; - color:#c0c0c0; -} - -.blog_holder article.format-link .post_text:hover .post_text_inner, -.blog_holder article.format-quote .post_text:hover .post_text_inner { - background-color: #1abc9c !important; /* it should be important so it can override default color from options */ -} - -.blog_holder article.format-link .post_text:hover .post_text_inner, -.blog_holder article.format-quote .post_text:hover .post_text_inner { - border-color: #1abc9c !important; /* it should be important so it can override default color from options */ -} - -.blog_holder article.format-link .post_text:hover .post_info, -.blog_holder article.format-link .post_text:hover .post_info a, -.blog_holder article.format-quote .post_text:hover .post_info, -.blog_holder article.format-quote .post_text:hover .post_info a, -.blog_holder article.format-quote .blog_like a:hover span, -.blog_holder article.format-quote .post_text:hover .quote_author, -.blog_holder article.format-quote .post_text:hover i.qoute_mark, -.blog_holder article.format-link .post_text:hover i.link_mark, -.blog_holder.blog_large_image_with_dividers article.format-quote .post_text:hover span.qoute_mark, -.blog_holder.blog_large_image_with_dividers article.format-link .post_text:hover span.link_mark, -.blog_holder.blog_large_image_with_dividers article.format-quote .post_text:hover .quote_author, -.blog_holder article.format-link .blog_like a:hover span, -.blog_holder article.format-quote .post_text:hover p a, -.blog_holder article.format-link .post_text:hover p a, -.blog_holder.blog_single article.format-quote .post_text:hover p, -.blog_holder.blog_single article.format-link .post_text:hover p, -.blog_large_image_simple article.format-quote .post_text:hover .minimalist_date, -.blog_large_image_simple article.format-link .post_text:hover .minimalist_date, -.blog_holder.masonry article.format-link .post_text:hover .post_info, -.blog_holder.masonry article.format-link .post_text:hover .post_info a, -.blog_holder.masonry article.format-quote .post_text:hover .post_info, -.blog_holder.masonry article.format-quote .post_text:hover .post_info a, -.blog_holder.masonry_full_width article.format-link .post_text:hover .post_info, -.blog_holder.masonry_full_width article.format-link .post_text:hover .post_info a, -.blog_holder.masonry_full_width article.format-quote .post_text:hover .post_info, -.blog_holder.masonry_full_width article.format-quote .post_text:hover .post_info a -{ - color:#fff; -} -.blog_holder.blog_single article h2{ - display: block; -} -.blog_load_more_button_holder { - text-align: center; - padding:0 0 40px; -} - -.blog_load_more_button_loading { - display: none; -} - -.single_links_pages{ - margin: 50px 0 0; - display: block; - text-align:center; - display: block; - text-decoration: none; -} - -.single_links_pages span{ - position: relative; - display: inline-block; - width: 38px; - height: 38px; - line-height: 38px; - margin: 0 11px 0 0; - text-align: center; - color: #303030; - text-decoration: none; - text-transform: uppercase; - cursor: pointer; - white-space: nowrap; - border: 2px solid #e3e3e3; - background-color: #e3e3e3; - outline: none; - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - -} -.single_links_pages a span { - color: #b4b4b4; - background-color:transparent; - border-color: #e5e5e5; -} -.single_links_pages a:hover span{ - background-color: #e3e3e3; - border-color: #e3e3e3; - color: #303030; -} -.author_description{ - display: block; - position: relative; - margin: 34px 0 0; - background-color:#fff; - padding:23px 23px; -} - -.author_description_inner{ - display: block; -} - -.author_description_inner .image{ - display: block; - width: 75px; - height: 75px; - float: left; - border-radius: 75px; - overflow:hidden; -} - -.author_text_holder { - padding: 0 0 0 100px; - min-height: 100px; - position:relative; -} - -.author_text_holder .author_name { - display: block; - margin: 0px 0 4px 0; -} - -.author_text_holder .author_email{ - display:block; - margin: 0px 0 6px 0; - -} -.single_tags { - margin:26px 0px 0px 0px; -} -.single_tags a, -.widget .tagcloud a { - letter-spacing:1px; -} -.single_tags h5{ - display:inline-block; -} - -.widget .tagcloud a { - display: inline-block; - font-size: 13px !important; -} -.widget .tagcloud a:after{ - content:","; -} -.widget .tagcloud a:last-child:after{ - content:""; -} -.blog_social_and_comments{ - display: inline-block; - width: 100%; - margin: 0 0 20px; -} - -.comment_number_holder{ - display: inline-block; - float: left; -} - -.blog_single_social{ - display: inline-block; - float: right; -} - -.blog_single_social .blog_like{ - float: right; - margin: 0 0 0 15px; -} - -.comment_holder{ - padding: 28px 0 38px; - margin: 0 0 0; -} - -.comment_number_holder .comment_number{ - color: #000; -} - -.comment_holder .comment_number{ - margin:0 0 20px; -} - -.comment_number .comment_number_inner i{ - position: relative; - top: -1px; - padding:0 10px 0 0; -} - -.comment_holder ul.comment-list{ - list-style: none; - position: relative; - z-index: 150; - padding:0; -} - -.comment_holder .comment-list{ - margin: 0; -} - -.comment_holder .comment-list li{ - display: inline-block; - position: relative; - width: 100%; -} - -.comment_holder .comment-list li ul.children li:last-child{ - padding:0 0 0px; -} - -.comment_holder .comment-list > li{ - margin: 0 0 18px; -} - -.comment_holder .comment-list > li:last-child{ - margin: 0; -} - -.comment_holder .comment{ - padding: 23px; - background-color:#fff; -} - -.comment_holder .comment .image { - display: block; - width: 75px; - height: 75px; - float: left; - border-radius: 75px; - overflow: hidden; -} - -.comment_holder .comment .text { - padding: 0 0 0 100px; - min-height: 80px; - position:relative; -} - -.comment_holder .comment .text .name { - display: block; - color: #303030; -} - -.comment_holder .comment .text .replay, -.comment_holder .comment .text .comment-reply-link { - color: #1abc9c; - font-size:9px; - text-transform:uppercase; - font-weight:700; - padding:0 0 0 5px; -} - -.comment_holder .comment .text .text_holder { - display: block; - margin:3px 0 0 0; -} - -.comment_holder .comment .logged-in-as { - margin: 10px 0; -} - -.comment_holder .comment .form-submit { - margin: 0 0 20px; -} - -.comment_holder .comment-list li ul.children { - margin: 18px 0 0 0; - padding: 0 0 0 70px; -} - -.comment_holder .comment-list li ul.children li{ - margin: 0px; - border-bottom:none; -} - -#respond h3 { - margin: 0 0 15px 0; -} -#respond h3.comment-reply-title{ - margin:0; - -} -#respond small { - display: block; - margin: 0 0 12px; - position: relative; -} -.comment_holder .comment .comment-respond{ - margin-top: 20px; -} - -#respond textarea, -#respond input[type='text'], -.contact_form input[type='text'], -.contact_form textarea { - width:100%; - margin: 0 0 20px 0; - padding: 15px 12px; - border: 0; - outline: 0; - resize: none; - font-size: 13px; - line-height:17px; - background-color:#fff; - color: #818181; - font-family: 'Raleway'; - font-weight:400; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -#respond textarea { - padding: 12px; -} - -.comment_holder #respond textarea, -.comment_holder #respond input[type='text']{ - background-color: #fff; -} -.comment_holder .comment #respond textarea, -.comment_holder .comment #respond input[type='text']{ - background-color: #f6f6f6; -} -.comment_holder #respond textarea { - margin: 0 0 12px; -} - -div.comment_form { - display: inline-block; - margin: 0 0 30px; - width: 100%; -} - -div.comment_form form p.form-submit, -div.comment_holder .comment p.form-submit { - margin: 0; - text-align: right; -} - -div.comment_form form p.form-submit .success p{ - margin: 10px 0 0; -} - -div.comment_form form p.logged-in-as{ - margin: 0 0 17px; -} - -#cancel-comment-reply-link { - margin: 0px; - display: inline-block; - width: 100%; -} -body.page-template-blog-masonry-full-width-php .content .full_width { - padding: 0 20px 25px 45px; -} - -body.page-template-blog-masonry-full-width-php.vertical_menu_enabled .content .full_width{ - padding-left:305px; -} - -.blog_holder.masonry, -.blog_holder.masonry_full_width { - margin-bottom: 20px; - transition: none !important; - overflow: visible !important; - opacity: 0; - filter: alpha(opacity=0); -} -#infscr-loading{ - position: absolute; - bottom:-15px; - left: 50%; -} -.blog_infinite_scroll_button{ - display: none; -} -.blog_holder.masonry article, -.blog_holder.masonry_full_width article{ - margin: 0 0 30px; - padding: 0; - text-align: left; - vertical-align: top; - z-index: 100; - border: 0; -} - -.blog_holder.masonry article, -.blog_holder.masonry .blog_holder_grid_sizer{ - width: 31.2%; -} - -.blog_holder.masonry .blog_holder_grid_gutter{ - width: 3.2%; -} - -.blog_holder.masonry_full_width .blog_holder_grid_sizer, -.blog_holder.masonry_full_width article{ - width: 18.7%; -} - -.blog_holder.masonry_full_width .blog_holder_grid_gutter{ - width: 1.6%; -} - -.two_columns_75_25 .blog_holder.masonry article, -.two_columns_75_25 .blog_holder.masonry .blog_holder_grid_sizer, -.two_columns_66_33 .blog_holder.masonry article, -.two_columns_66_33 .blog_holder.masonry .blog_holder_grid_sizer, -.two_columns_33_66 .blog_holder.masonry article, -.two_columns_33_66 .blog_holder.masonry .blog_holder_grid_sizer, -.two_columns_25_75 .blog_holder.masonry article, -.two_columns_25_75 .blog_holder.masonry .blog_holder_grid_sizer{ - width:48%; -} - -.two_columns_75_25 .blog_holder.masonry .blog_holder_grid_gutter, -.two_columns_66_33 .blog_holder.masonry .blog_holder_grid_gutter, -.two_columns_33_66 .blog_holder.masonry .blog_holder_grid_gutter, -.two_columns_25_75 .blog_holder.masonry .blog_holder_grid_gutter{ - width: 4%; -} - -.blog_holder.masonry article:hover{ - z-index: 200; -} - -.blog_holder.masonry article .post_image{ - margin: 0; - width: auto; -} - -.blog_holder.masonry article .post_info, -.blog_holder.masonry_full_width article .post_info{ - margin:15px 0 0 0; - color:#303030; -} -.blog_holder.masonry article.format-link .post_info, -.blog_holder.masonry_full_width article.format-link .post_info, -.blog_holder.masonry_full_width article.format-quote .post_info, -.blog_holder.masonry article.format-quote .post_info{ - margin: 0 0 20px; -} -.blog_holder.masonry article .post_text .post_text_innet, -.blog_holder.masonry_full_width article .post_text .post_text_innet{ - padding: 20px 15px 20px 15px; -} - -.blog_holder.masonry article.format-link .post_text, -.blog_holder.masonry_full_width article.format-link .post_text, -.blog_holder.masonry article.format-quote .post_text, -.blog_holder.masonry_full_width article.format-quote .post_text{ - border:none; -} - -.blog_holder article.format-quote h3{ - margin:0 0 10px; - line-height:35px; -} - -.blog_holder.masonry article h4, -.blog_holder.masonry_full_width article h4{ - margin:0 0 4px; -} - -.blog_holder.masonry article h3 a{ - font-weight: 300; -} - -.blog_holder.masonry article.format-link .post_text, -.blog_holder.masonry_full_width article.format-link .post_text, -.blog_holder.masonry_full_width article.format-quote .post_text, -.blog_holder.masonry article.format-quote .post_text{ - padding: 0; -} - -.blog_holder.masonry article .mejs-controls div.mejs-horizontal-volume-slider, -.blog_holder.masonry_full_width article .mejs-controls div.mejs-horizontal-volume-slider{ - margin: 0 10px 0 0; -} - -.blog_holder.blog_masonry_date_in_image .time{ - position: absolute; - top: 0; - left: 0; - text-align: center; - margin: 5px; - padding: 5px 13px; - background-color: #fff; -} - -.blog_holder.blog_masonry_date_in_image .time span{ - display: block; -} - -.blog_holder.blog_masonry_date_in_image .time .time_day{ - color: #303030; - font-size: 19px; - font-weight: 600; -} - -.blog_holder.blog_masonry_date_in_image article .post_text .post_text_inner{ - text-align: center; - padding: 35px 5px; -} - -.blog_holder.blog_masonry_date_in_image article.format-quote .post_text .post_text_inner, -.blog_holder.blog_masonry_date_in_image article.format-link .post_text .post_text_inner{ - padding: 35px 15px; -} - -.blog_holder.blog_masonry_date_in_image article .post_text h5{ - margin-bottom: 30px; -} - -.blog_holder.blog_masonry_date_in_image .post_text_inner .social_share_list_holder > span{ - display: none; -} - -.blog_holder.blog_masonry_date_in_image article .post_text_inner .post_info{ - margin-top: 35px; - margin-bottom: 0; -} - -.blog_holder.blog_masonry_date_in_image .social_share_list_holder ul li i{ - color: #8d8d8d; - -webkit-transition: color 0s ease-in-out; - -moz-transition: color 0s ease-in-out; - -ms-transition: color 0s ease-in-out; - -o-transition: color 0s ease-in-out; - transition: color 0s ease-in-out; -} - -.blog_holder.blog_masonry_date_in_image article:not(.format-quote):not(.format-link) .social_share_list_holder ul li i:hover{ - color: #1abc9c; -} - -.blog_holder.blog_masonry_date_in_image article.format-quote .post_text:hover .social_share_list_holder ul li i, -.blog_holder.blog_masonry_date_in_image article.format-link .post_text:hover .social_share_list_holder ul li i{ - color: #fff !important; -} - - -.isotope-item { - z-index: 2; -} - -.isotope-hidden.isotope-item { - pointer-events: none; - z-index: 1; -} - -/**** Isotope CSS3 transitions ****/ - -/*.isotope, -.isotope .isotope-item { - -webkit-transition-duration: 0.8s; - -moz-transition-duration: 0.8s; - -ms-transition-duration: 0.8s; - -o-transition-duration: 0.8s; - transition-duration: 0.8s; -}*/ - - -.isotope { - -webkit-transition-property: height; - -moz-transition-property: height; - -ms-transition-property: height; - -o-transition-property: height; - transition-property: height; -} - -.isotope .isotope-item { - -webkit-transition-property: -webkit-transform, opacity; - -moz-transition-property: -moz-transform, opacity; - -ms-transition-property: -ms-transform, opacity; - -o-transition-property: -o-transform, opacity; - transition-property: transform, opacity; -} - -.isotope.no-transition, -.isotope.no-transition .isotope-item, -.isotope .isotope-item.no-transition { - -webkit-transition-duration: 0s; - -moz-transition-duration: 0s; - -ms-transition-duration: 0s; - -o-transition-duration: 0s; - transition-duration: 0s; -} - -/*************************** BLOG END **************************/ - -/* ========================================================================== - Pagination styles - ========================================================================== */ -.pagination { - display: inline-block; - width: 100%; - text-align: center; - margin: 0px 0px 50px; - position:relative; -} - -.pagination ul { - display: inline-block; - list-style-type: none; - margin: 0px; - padding: 0px; -} - -.pagination ul li { - float: left; -} - -.pagination ul li span, -.pagination ul li a{ - position: relative; - display: inline-block; - width: 38px; - height: 38px; - line-height: 38px; - margin: 0 11px 0 0; - text-align:center; - color: #b4b4b4; - font-size: 18px; - text-decoration: none; - text-transform: uppercase; - cursor: pointer; - white-space: nowrap; - border: 2px solid #e5e5e5; - outline: none; - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; -} - -.pagination ul li span, -.pagination ul li a:hover{ - color: #303030; - background-color: #e3e3e3; - border-color: #e3e3e3; -} - -/* ========================================================================== - End of Pagination styles - ========================================================================== */ - -.google_map_holder, -.google_map_shortcode_holder -{ - position: relative; -} - -.google_map_ovrlay { - position: absolute; - z-index: 1000; - width: 100%; - height: 100%; - display: none; -} -.google_map_shortcode_overlay{ - position: absolute; - z-index: 1000; - width: 100%; - height: 100%; - display: none; - top:0; - left:0; -} -.google_map { - display: block; - width: 100%; - height: 450px; - margin:0 0 25px; - -} -.qode_google_map { - display: block; - width: 100%; - height: 450px; -} - -.google_map iframe, -.google_map object, -.google_map embed, -.qode_google_map iframe, -.qode_google_map object, -.qode_google_map embed { - width: 100%; - display: block; -} - -.google_map img, -.qode_google_map img -{ - max-width: none; -} - -.contact_form h5{ - margin:0 0 18px; -} -.contact_info .q_social_icon_holder .fa-stack { - margin:0.2307692307692308em 0.4615384615384616em 0.2307692307692308em 0; -} -.contact-error{ - display: block; - margin: 0; - position: relative; - top: -20px; -} -.contact_section{ - text-align:center; - padding:0 0 55px; -} -.contact_section.contact_section_position_left{ - text-align: left; -} -.contact_section.contact_section_position_right{ - text-align: right; -} -.contact_section .separator, -.contact_section .separator.small.right, -.contact_section .separator.small.left -{ - margin-top:6px; - margin-bottom:35px; -} -span.submit_button_contact { - display: block; - text-align: right; -} - -.contact_form { - margin:0 0 50px; -} - -.contact_detail.map_grid .google_map{ - margin:0 0 35px; -} - -.header-widget.widget_nav_menu { - padding:0 15px 0 0; - position:relative; - font-size:12px; -} - -.header-widget.widget_nav_menu ul ul { - display:none; - height: auto; - border-top: none; - background-color: #262626; - z-index: 1010; - position: absolute; - top: 33px; - left: -1px; - width: 180px; - padding:0px; -} - -.header-widget.widget_nav_menu ul li:hover ul{ - display:block; -} - -.header-widget.widget_nav_menu ul li{ - list-style:none; -} - -.header-widget.widget_nav_menu ul.menu > li { - display: inline-block; - float:left; - position:relative; -} - -.header-widget.widget_nav_menu ul.menu li a{ - display: inline-block; - padding:0 0px 0 15px; - color:#777; -} - -.header-widget.widget_nav_menu ul.menu > li.menu-item-has-children > a:after { - content: "\f107"; - font-family: 'FontAwesome', sans-serif; - margin-left: 5px; -} - -.header-widget.widget_nav_menu ul.menu li a:hover{ - color:#1abc9c; -} - -.header-widget.widget_nav_menu ul.menu li ul li a{ - color: #9d9d9d; - display: block; - white-space: nowrap; - font-size: 11px; - font-weight: 600; - line-height: 38px; - padding: 0 15px; - border-bottom: 1px solid #303030; - text-transform: uppercase; -} - -.header-widget.widget_nav_menu ul.menu li ul li:last-child a{ - border-bottom:0; -} - -.header-widget ul.menu li:last-child { - margin-right: 0; -} - -.header-left-from-logo-widget, -.header-right-from-logo-widget{ - display: block; - height: 100%; - position: absolute; - top: 0px; - left: 0px; - padding: 0px 50px; -} - -.header-right-from-logo-widget{ - left: auto; - right: 0px; -} - -header .container_inner .header-left-from-logo-widget, -header .container_inner .header-right-from-logo-widget{ - padding: 0px; -} - -.header-left-from-logo-widget-inner, -.header-right-from-logo-widget-inner{ - display: table; - height: 100%; -} - -.header-left-from-logo-widget-inner2, -.header-right-from-logo-widget-inner2{ - display: table-cell; - height: 100%; - vertical-align: middle; -} - -header.sticky .header-left-from-logo-widget, -header.sticky .header-right-from-logo-widget{ - display: none; -} - -/* ========================================================================== - Sidebar and side menu styles - ========================================================================== */ -/** - * Common sidebar, side menu and widgets styles that are placed in this widget areas - */ - -.container aside { - position: relative; - z-index: 11; -} - -aside .widget a, -.side_menu a, -.side_menu .widget li { - font-weight: 400; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - -aside .widget a:hover{ - color: #1abc9c; -} - -.side_menu .widget a:hover, -.side_menu .widget li:hover, -.side_menu .widget li:hover > a { - color: #fff; -} - -aside .widget ul, -.side_menu .widget ul{ - list-style: none; - padding:0; -} - -aside .widget li, -.side_menu .widget li{ - margin: 0 0 10px; -} - -aside .widget li:last-child, -.side_menu .widget li:last-child{ - margin: 0; -} - -.widget.widget_rss li a.rsswidget, -#wp-calendar caption{ - color: #000; -} - -.footer_top .widget.widget_rss li a.rsswidget, -.footer_top #wp-calendar caption{ - color: #fff; -} - -#wp-calendar th, -#wp-calendar td{ - padding: 3px 4px; -} - -#wp-calendar td#today { - color: #fff; - background-color: #1abc9c; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} - -#wp-calendar{ - width: 100%; - text-align: center; -} - -.widget.widget_rss li span.rss-date, -#wp-calendar caption{ - margin: 0 0 15px; -} - -.widget.widget_rss li{ - margin: 0 0 25px; -} - -/* Sidebar styles - ========================================================================== */ -/** - * Sidebar specific styles - */ - -aside .widget.widget_search{ - border-bottom: 0px; - padding: 0; -} - -aside .widget h5 { - margin-bottom: 14px; -} - -aside .widget.posts_holder li { - padding: 7px 0px 7px 0px; - margin: 0; -} - -aside .widget.posts_holder li.page_item_has_children > ul.children li:last-child, -aside .widget.posts_holder li.menu-item-has-children > ul.sub-menu li:last-child{ - border-bottom: 0; -} - -aside .widget.posts_holder li:hover{ - color: #1abc9c; -} - -aside .widget.posts_holder li.page_item_has_children > ul.children, -aside .widget.posts_holder li.menu-item-has-children > ul.sub-menu { - padding-left: 10px; -} - -aside .widget.posts_holder li.page_item_has_children > a, -aside .widget.posts_holder li.menu-item-has-children > a { - display: block; -} - -aside .widget a { - color: inherit; -} - -aside .widget{ - margin: 0 0 42px; -} - -aside .widget_nav_menu .sub-menu, -aside .widget_pages .children { - margin-left: 20px; - margin-top: 6px; -} - -/* Side menu styles - ========================================================================== */ -/** - * Side menu specific styles - */ - - -.side_menu{ - background-color: #1b1b1b; - height: 100%; - min-height: 100%; - overflow: hidden; - padding: 30px; - position: fixed; - top: 0; - right: -270px; - width: 270px; - z-index: 90; - visibility: hidden; - -webkit-backface-visibility: hidden; - box-sizing:border-box; -} - -/* Side Menu Slides Over Content */ - -.right_side_menu_opened .wrapper, -.right_side_menu_opened footer.uncover{ - left:-270px; -} -.side_menu_slide_from_right .wrapper{ - background-color: #fff; - position: relative; - z-index: 1000; - -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - -ms-transform:translateX(0,0); - -moz-transform:translateX(0,0); - -o-transform:translateX(0,0); - transform:translateX(0,0); - -webkit-transform:translateX(0,0); -} - -.side_menu_slide_from_right.right_side_menu_opened .wrapper{ - transform:translateX(-270px,0); - -ms-transform:translateX(-270px,0); - -moz-transform:translateX(-270px,0); - -webkit-transform:translateX(-270px,0); - -o-transform:translateX(-270px,0); - -moz-transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); - -o-transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); - -webkit-transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); - transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); -} - - -.side_menu_slide_from_right .carousel-inner { - -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -} - -.side_menu_slide_from_right .wrapper .cover{ - z-index: 0; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - opacity: 0; - filter: alpha(opacity=0); - background:#000; - -moz-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; - -webkit-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; -} - -.side_menu_slide_from_right.right_side_menu_opened .wrapper .cover{ - z-index: 1002; - opacity: 0.6; - filter: alpha(opacity=60); - -moz-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; - -webkit-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; -} - -.side_menu_slide_from_right .side_menu { - padding: 5% 30px 30px 30px; - top: 0; - right: -45%; - width: 45%; - z-index: 9999; - text-align: center; - visibility: hidden; - -moz-transition: 0.2s ease-in-out; - -o-transition: 0.2s ease-in-out; - -webkit-transition: 0.2s ease-in-out; - transition: 0.2s ease-in-out; - -webkit-box-sizing:border-box; - box-sizing: border-box; -} -.right_side_menu_opened.side_menu_slide_from_right .side_menu { - right: 0px; - visibility: visible; - -moz-transition: right 0.2s ease-in-out; - -o-transition: right 0.2s ease-in-out; - -webkit-transition: right 0.2s ease-in-out; - transition: right 0.2s ease-in-out; -} - -.side_menu_slide_from_right header.sticky, -.side_menu_slide_from_right header.fixed_top_header .top_header, -.side_menu_slide_from_right header.fixed, -.side_menu_slide_from_right header.fixed_hiding, -.side_menu_slide_from_right header.fixed_top_header .top_header{ - -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -} - -.side_menu_slide_from_right footer.uncover { - -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); - transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -} - -/* Side Menu Slides With Content */ - -body.side_menu_slide_with_content{ - overflow-x: hidden; - position: relative; - left: 0; - -webkit-overflow-scrolling:auto !important; -} - -body.side_menu_slide_with_content.side_menu_open .wrapper, -body.side_menu_slide_with_content.side_menu_open footer.uncover{ - left: -470px; -} - -body.side_menu_slide_with_content .wrapper{ - -webkit-transition: left 0.2s ease, right 0.2s ease; - -moz-transition: left 0.2s ease, right 0.2s ease; - transition: left 0.2s ease, right 0.2s ease; -} - -body.side_menu_slide_with_content .side_menu, -body.side_menu_slide_with_content, -body.side_menu_slide_with_content header.fixed, -body.side_menu_slide_with_content header.fixed_top_header .top_header, -body.side_menu_slide_with_content header.fixed_hiding, -body.side_menu_slide_with_content footer.uncover{ - -webkit-transition: left 0.2s ease, right 0.2s ease; - -moz-transition: left 0.2s ease, right 0.2s ease; - transition: left 0.2s ease, right 0.2s ease; -} - -body.side_menu_slide_with_content header.sticky{ - -webkit-transition: left 0.2s ease, right 0.2s ease, top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -moz-transition: left 0.2s ease, right 0.2s ease, top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - transition: left 0.2s ease, right 0.2s ease, top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -} - -body.side_menu_slide_with_content .side_menu{ - position: fixed; - visibility: visible; - -webkit-box-sizing:border-box; - box-sizing: border-box; - width: 470px; - right: -470px; - height: 100%; - top: 0; - z-index: 9999; -} - -body.side_menu_slide_with_content.side_menu_open .side_menu { - right: 0; -} - -body.side_menu_slide_with_content.side_menu_open .carousel-inner:not(.relative_position){ - left:-470px !important; - -webkit-transition: left 0.2s ease; - -moz-transition: left 0.2s ease; - transition: left 0.2s ease; -} - -body.side_menu_slide_with_content .carousel-inner { - left:0 !important; - -webkit-transition: left 0.2s ease; - -moz-transition: left 0.2s ease; - transition: left 0.2s ease; -} - -body.side_menu_slide_with_content.side_menu_open header.fixed, -body.side_menu_slide_with_content.side_menu_open header.fixed_top_header .top_header, -body.side_menu_slide_with_content.side_menu_open header.fixed_hiding, -body.side_menu_slide_with_content.side_menu_open header.sticky{ - left: -470px; - -webkit-transition: left 0.2s ease; - -moz-transition: left 0.2s ease; - transition: left 0.2s ease; -} - -/* width 270px start */ - -body.side_menu_slide_with_content.width_270.side_menu_open .wrapper, -body.side_menu_slide_with_content.width_270.side_menu_open footer.uncover{ - left: -270px; -} - -body.side_menu_slide_with_content.width_270 .side_menu{ - width: 270px; - right: -270px; -} - -body.side_menu_slide_with_content.width_270.side_menu_open .side_menu { - right: 0; -} - -body.side_menu_slide_with_content.width_270.side_menu_open .carousel-inner:not(.relative_position){ - left:-270px !important; - -} - -body.side_menu_slide_with_content.width_270.side_menu_open header.fixed, -body.side_menu_slide_with_content.width_270.side_menu_open header.fixed_hiding, -body.side_menu_slide_with_content.width_270.side_menu_open header.sticky, -body.side_menu_slide_with_content.width_270.side_menu_open header.fixed_top_header .top_header{ - left: -270px; -} - -/* width 270px end */ - -/* width 370px start */ - -body.side_menu_slide_with_content.width_370.side_menu_open .wrapper, -body.side_menu_slide_with_content.width_370.side_menu_open footer.uncover{ - left: -370px; -} - -body.side_menu_slide_with_content.width_370 .side_menu{ - width: 370px; - right: -370px; -} - -body.side_menu_slide_with_content.width_370.side_menu_open .side_menu { - right: 0; -} - -body.side_menu_slide_with_content.width_370.side_menu_open .carousel-inner:not(.relative_position){ - left:-370px !important; - -} - -body.side_menu_slide_with_content.width_370.side_menu_open header.fixed, -body.side_menu_slide_with_content.width_370.side_menu_open header.fixed_hiding, -body.side_menu_slide_with_content.width_370.side_menu_open header.sticky, -body.side_menu_slide_with_content.width_370.side_menu_open header.fixed_top_header .top_header{ - left: -370px; -} - -/* width 370px end */ - -/* Side Menu Slides With Content - End */ - - -.side_menu.side_area_alignment_left{ - text-align: left; -} -.side_menu.side_area_alignment_center{ - text-align: center; -} -.side_menu.side_area_alignment_right{ - text-align: right; -} -.side_menu h5, -.side_menu h6{ - margin: 0 0 12px 0; - color: #fff; -} - -.side_menu .widget li { - position:relative; -} - -.side_menu .widget ul li.page_item_has_children, -.side_menu .widget ul li.menu-item-has-children{ - padding-right: 0; - border-bottom:none; -} - -.side_menu .widget ul ul{ - padding: 6px 0 0 20px; -} - -.side_menu .widget{ - margin: 0 0 43px; -} - -.side_menu a, -.side_menu li, -.side_menu span, -.side_menu p, -.side_menu .widget.widget_rss li a.rsswidget, -.side_menu #wp-calendar caption, -.side_menu #wp-calendar th, -.side_menu #wp-calendar td{ - color: #818181; -} - -.side_menu .side_menu_title{ - display: block; - margin: 0 0 12px; -} - - -.side_menu .widget.widget_nav_menu li:last-child, -.side_menu .widget.widget_nav_menu li a{ - margin: 0; -} - -.side_menu a.close_side_menu { - display: inline-block; - position: absolute; - top: 29px; - right: 25px; - width: 13px; - height: 13px; - line-height: 13px; - background-image: url('img/close_side_menu.png'); - background-repeat: no-repeat; - z-index: 1000; - -webkit-transition: all .5s ease; - -moz-transition: all .5s ease; - -ms-transition: all .5s ease; - -o-transition: all .5s ease; - transition: all .5s ease; -} -.side_menu a.close_side_menu:hover{ - transform: rotate(180deg); - -ms-transform: rotate(180deg); - -webkit-transform: rotate(180deg); - -o-transform: rotate(180deg); - -moz-transform: rotate(180deg); -} -@media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { - .side_menu a.close_side_menu { - background-image: url("img/close_side_menu@2x.png"); - -o-background-size: 13px 13px; - -webkit-background-size: 13px 13px; - -moz-background-size: 13px 13px; - background-size: 13px 13px; - } -} - -@media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { - .side_menu a.close_side_menu { - background-image: url("img/close_side_menu@2x.png"); - -o-background-size: 13px 13px; - -webkit-background-size: 13px 13px; - -moz-background-size: 13px 13px; - background-size: 13px 13px; - } -} - -.side_menu.dark a.close_side_menu { - background-image: url('img/close_side_menu_dark.png'); -} - -@media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { - .side_menu.dark a.close_side_menu { - background-image: url("img/close_side_menu_dark@2x.png"); - -o-background-size: 13px 13px; - -webkit-background-size: 13px 13px; - -moz-background-size: 13px 13px; - background-size: 13px 13px; - } -} - -@media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { - .side_menu.dark a.close_side_menu { - background-image: url("img/close_side_menu_dark@2x.png"); - -o-background-size: 13px 13px; - -webkit-background-size: 13px 13px; - -moz-background-size: 13px 13px; - background-size: 13px 13px; - } -} - -/* ========================================================================== - End of sidebar and side menu styles - ========================================================================== */ - -.footer_top .widget.widget_nav_menu li{ - margin: 0 0 0px; - line-height: 22px; -} - -.widget.widget_archive select, -.widget.widget_categories select, -.widget.widget_text select { - width: 100%; - overflow: hidden; - border: 1px solid transparent; - font-size: 13px; - background-color: #fff; - outline: 0px; - color: #818181; - font-family: inherit; - padding: 2px 4%; - height: 37px; -} - -.widget #searchform { - display: inline-block; - width: 100%; - overflow: hidden; - background-color: #fff; -} - -.footer_top .widget #searchform{ - background-color: transparent; - border: 1px solid #6a6a6a; -} -.header_top #searchform { - padding: 0 10px; - height: 33px; -} - -.widget.widget_search form.form_focus { - border-color: #1abc9c; -} - -.widget.widget_search form input[type="submit"], -.header_top #searchform input[type="submit"]{ - width: 37px; - height: 37px; - line-height: 37px; - display: inline-block; - margin: 0; - padding: 0 4%; - outline: none; - border: none; - text-decoration: none; - background-color: transparent; - color: #b9b9b9; - font-family: 'FontAwesome', sans-serif; - cursor: pointer; - white-space: nowrap; - float: right; - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - -ms-transition: all 0.2s ease-in-out; -} - -.footer_top .widget #searchform input[type="submit"]{ - color: #6a6a6a; -} - -.header_top #searchform input[type="submit"]{ - width: 22px; - height: 25px; - line-height: 25px; - margin: 4px 0 0; - background: none; -} - -.widget.widget_search form .screen-reader-text, -.header_top #searchform .screen-reader-text{ - display: none; -} - -.widget.widget_search form input[type="text"], -.header_top #searchform input[type="text"]{ - display: inline-block; - text-decoration: none; - border: 0; - outline: 0px; - color: #adadad; - background-color: transparent; - font-family: inherit; - margin: 0; - padding: 2px 4%; - width: 74%; - height: 33px; - float: left; -} -.footer_top .widget #searchform input[type="text"]{ - color: #6a6a6a; -} -.header_top #searchform input[type="text"]{ - height: 29px; - font-size: 12px; -} - -.side_menu .widget #searchform input[type="text"], -.footer_top .widget.widget_search form input[type="text"]{ - width: 70% !important; -} - -.widget .tagcloud { - display:inline-block; - width:100%; -} - -.widget .tagcloud a { - margin: 0 0px 3px 0; -} - -.side_menu .widget .tagcloud a { - color: #fff; -} - -footer{ - display: block; - width: 100%; - margin: 0px auto; - z-index: 100; - position: relative; -} - -footer.uncover{ - position: fixed; - bottom: 0px; - left: 0px; - z-index: 99; - -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -webkit-backface-visibility: hidden; -} - -.boxed footer{ - width: 100% !important; - box-sizing:border-box; - -moz-box-sizing:border-box; /* Firefox */ -} - -.right_side_menu_opened footer.uncover{ - left: -270px; -} - -footer .container_inner{ - position: relative; -} - -.footer_top_holder{ - display: block; - background-color: #262626; - position: relative; -} - -.footer_top{ - padding: 72px 0px 52px; -} - -.footer_top_border.in_grid, -.footer_bottom_border.in_grid { - width: 1100px; - margin: 0 auto; -} - -.footer_top.footer_top_full{ - padding: 48px 24px; -} - -.footer_top h5{ - color: #fff; - margin: 0 0 22px; -} - -.footer_top ul{ - list-style: none; -} - -.footer_top a, -.footer_top p, -.footer_top span, -.footer_top li, -.footer_top .textwidget -{ - color: #818181; - word-wrap: break-word; -} - -.footer_top a{ - -webkit-transition: color 0.2s ease-in-out; - -moz-transition: color 0.2s ease-in-out; - -o-transition: color 0.2s ease-in-out; - -ms-transition: color 0.2s ease-in-out; -} - -.footer_top a:hover{ - color:#fff !important; -} -.footer_top .four_columns .column2 .column_inner > div, -.footer_top .three_columns .column2 .column_inner > div, -.footer_top .two_columns_50_50 .column2 .column_inner > div{ - margin: 0 0 0 15px; -} - -.footer_top .four_columns .column3 .column_inner > div, -.footer_top .three_columns .column3 .column_inner > div{ - margin: 0 0 0 10px; -} - -.footer_top .four_columns .column4 .column_inner > div{ - margin: 0 0 0 5px; -} - -.footer_top .widget_nav_menu li.menu-item a { - margin-bottom: 0; -} - -.footer_top .widget_recent_entries > ul > li, -.footer_top .widget_recent_comments > ul > li, -.footer_top .widget_meta > ul > li, -.footer_top .widget_nav_menu ul li, -.footer_top .widget_pages ul li { - padding: 0px 0px 17px; - position: relative; -} - -.footer_top .widget_nav_menu ul li ul, -.footer_top .widget_pages ul li ul{ - padding:0 0 0 10px; -} - -.footer_top .widget_recent_entries > ul > li > a, -.footer_top .widget_pages > ul > li > a, -.footer_top .widget_meta > ul > li > a, -.footer_top .widget_nav_menu ul li a, -.footer_top .widget_recent_comments > ul > li > a, -.footer_top .widget_recent_entries > ul > li > span { - display: block; -} -.footer_top .widget_recent_entries > ul > li > span { - color:#9d9d9d; -} -.footer_bottom_holder { - display: block; - background-color: #1b1b1b; -} -.footer_top_holder svg.angled-section polygon{ - fill:#1b1b1b; -} -.footer_bottom { - display: table-cell; - text-align: center; - font-size: 12px; - line-height: 22px; - height: 53px; - width: 1%; - vertical-align: middle; -} -.footer_bottom_columns.three_columns .column1 .footer_bottom, -.footer_bottom_columns.two_columns_50_50 .column1 .footer_bottom, -.footer_bottom_columns.three_columns .column1 .footer_bottom ul, -.footer_bottom_columns.two_columns_50_50 .column1 .footer_bottom ul -{ - text-align: left; -} - -.footer_bottom_columns.three_columns .column3 .footer_bottom, -.footer_bottom_columns.two_columns_50_50 .column2 .footer_bottom, -.footer_bottom_columns.three_columns .column3 .footer_bottom ul, -.footer_bottom_columns.two_columns_50_50 .column2 .footer_bottom ul -{ - text-align: right; -} -.footer_bottom p, -.footer_bottom span { - margin: 0px; -} - -.footer_bottom .footer_text_title { - display: none; -} - -.footer_bottom ul { - list-style: none; - text-align: center; -} - -.footer_bottom ul li { - display: inline-block; - margin-right: 46px; -} - -.footer_bottom ul li:last-child { - margin-right: 0; -} - -.footer_bottom ul li a { - color: #fff; - text-transform: uppercase; - font-weight: 500; - letter-spacing: 1px; - font-size: 13px; - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - -.footer_bottom ul li a:hover { - color: #818181; -} - -.footer_top .q_social_icon_holder i.simple_social { - margin-right:16px; -} -.footer_top .q_social_icon_holder i.simple_social, -.side_menu .q_social_icon_holder i.simple_social{ - color: #818181; -} -.footer_top .q_social_icon_holder:hover i.simple_social, -.side_menu .q_social_icon_holder:hover i.simple_social -{ - color: #fff !important; -} -.footer_top .q_social_icon_holder.normal_social{ - margin:0 0 0 0; -} -.footer_top .q_social_icon_holder:last-child i.simple_social{ - margin-right:0; -} - -.footer_top .q_social_icon_holder i.simple_social{ - -webkit-transition:all 0.3s ease 0s; - -moz-transition:all 0.3s ease 0s; - -o-transition:all 0.3s ease 0s; - transition:all 0.3s ease 0s; -} - - - -#back_to_top{ - color: #cdcdcd; - height: auto; - position: fixed; - bottom: 65px; - margin: 0px; - z-index: 10000; - -webkit-transition:all 0.3s ease 0s; - -moz-transition:all 0.3s ease 0s; - -o-transition:all 0.3s ease 0s; - transition:all 0.3s ease 0s; - right: 25px; - opacity: 0; - filter: alpha(opacity=0); - visibility: hidden; - -webkit-backface-visibility: hidden; -} - -#back_to_top.off{ - opacity: 0; - filter: alpha(opacity=0); - right: 25px; -} - -#back_to_top.on{ - opacity: 1; - filter: alpha(opacity=100); - visibility: visible; - right: 25px; -} - -#back_to_top .hover{ - display: none; -} - -#back_to_top span{ - width: 52px; - height: 52px; - line-height: 52px; - text-decoration: none; - -o-border-radius: 52px; - -moz-border-radius: 52px; - -webkit-border-radius: 52px; - border-radius: 52px; - -webkit-transition:all 0.2s ease 0s; - -moz-transition:all 0.2s ease 0s; - -o-transition:all 0.2s ease 0s; - border:2px solid #e8e8e8; - background:transparent; -} - -#back_to_top span i{ - font-size: 22px; - -webkit-transition: color 0.2s ease 0s; - -moz-transition: color 0.2s ease 0s; - -o-transition: color 0.2s ease 0s; - color:#b0b0b0; - line-height: 52px; -} - -#back_to_top:hover span{ - background-color:#e8e8e8; -} - -.right_side_menu_opened #back_to_top{ - display: none; -} - -/* ========================================================================== - Steps shortcode styles - ========================================================================== */ -.q_steps_holder { - width: 100%; - text-align: center; -} - -.q_steps_holder_inner { - position: relative; - display: inline-block; -} - -.q_steps_holder .circle_small, -.q_steps_holder .circle_small_inner { - width: 192px; - height: 192px; -} - -.q_steps_holder .circle_small_wrapper { - margin: 0 auto; - border-radius: 530px; - border: 2px solid transparent; - border-top: 2px solid #1abc9c; - width: 193px; - height: 192px; -} - -.q_steps_holder .circle_small { - margin: 0 auto; - border: 1px solid #c7c7c7; - color: #666666; - font-family: inherit; - font-size: 26px; - border-radius: 500px; - text-align: center; -} - -.q_steps_holder .circle_small:hover span, -.q_steps_holder .circle_small:hover .step_title { - color: #1abc9c !important; -} - -.q_steps_holder .circle_small_inner { - display: table-cell; - vertical-align: middle; -} -.q_steps_holder .circle_small_inner span{ - font-size: 50px; - font-weight:500; - line-height:50px; -} -.q_steps_holder a.circle_small_inner { - color: #666666; -} - -.q_steps_holder a.circle_small_inner:hover { - color: inherit; -} - -.q_steps_holder .circle_small span { - display: block; - margin-bottom: 5px; - -webkit-transition:color 0.2s ease 0s; - -moz-transition:color 0.2s ease 0s; - -o-transition:color 0.2s ease 0s; -} - -.q_steps_holder .circle_small .step_title { - color: #666666; - letter-spacing: 1px; - font-size: 16px; - -webkit-transition:color 0.2s ease 0s; - -moz-transition:color 0.2s ease 0s; - -o-transition:color 0.2s ease 0s; -} -.q_steps_holder .circle_small_holder p { - margin-top: 5px; - text-align: center; - padding: 0 21px; -} - -.q_steps_holder .circle_small_holder { - width: 265px; - display: inline-block; -} - -.q_steps_holder .circle_small_holder_inner { - position: relative; -} - -.q_steps_holder .circle_small_holder:last-child .circle_small_holder_inner .arrow_holder { - background: none; -} - -.q_steps_holder.show .circle_small_holder { - opacity: 1; - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); -} - -.q_steps_holder .circle_small_holder { - -webkit-transform: scale(0.7); - -moz-transform: scale(0.7); - -ms-transform: scale(0.7); - -o-transform: scale(0.7); - transform: scale(0.7); - opacity: 0; - -webkit-transition: all 0.3s ease-out; - -moz-transition: all 0.3s ease-out; - -o-transition: all 0.3s ease-out; - transition: all 0.3s ease-out; -} - -.q_steps_holder .step1 { - left: 40px; - top: 85px; - -webkit-transition-delay: 0.5s; - -moz-transition-delay: 0.5s; - -ms-transition-delay: 0.5s; - -o-transition-delay: 0.5s; - transition-delay: 0.5s; -} - -.q_steps_holder .step1 .circle_small_wrapper { - transform:rotate(-25deg); - -ms-transform:rotate(-25deg); /* IE 9 */ - -webkit-transform:rotate(-25deg); /* Safari and Chrome */ -} - -.q_steps_holder .step1 .circle_small { - transform:rotate(25deg); - -ms-transform:rotate(25deg); /* IE 9 */ - -webkit-transform:rotate(25deg); /* Safari and Chrome */ -} - -.q_steps_holder .step2 { - -webkit-transition-delay: 1s; - -moz-transition-delay: 1s; - -ms-transition-delay: 1s; - -o-transition-delay: 1s; - transition-delay: 1s; -} - -.q_steps_holder .step2 .circle_small_wrapper { - transform:rotate(-175deg); - -ms-transform:rotate(-175deg); /* IE 9 */ - -webkit-transform:rotate(-175deg); /* Safari and Chrome */ -} - -.q_steps_holder .step2 .circle_small { - transform:rotate(175deg); - -ms-transform:rotate(175deg); /* IE 9 */ - -webkit-transform:rotate(175deg); /* Safari and Chrome */ -} - -.q_steps_holder .step3 { - -webkit-transition-delay: 1.5s; - -moz-transition-delay: 1.5s; - -ms-transition-delay: 1.5s; - -o-transition-delay: 1.5s; - transition-delay: 1.5s; -} - -.q_steps_holder .step3 .circle_small_wrapper { - transform:rotate(25deg); - -ms-transform:rotate(25deg); /* IE 9 */ - -webkit-transform:rotate(25deg); /* Safari and Chrome */ -} - -.q_steps_holder .step3 .circle_small { - transform:rotate(-25deg); - -ms-transform:rotate(-25deg); /* IE 9 */ - -webkit-transform:rotate(-25deg); /* Safari and Chrome */ -} - -.q_steps_holder .step4 .circle_small_wrapper { - transform:rotate(-170deg); - -ms-transform:rotate(-170deg); /* IE 9 */ - -webkit-transform:rotate(-170deg); /* Safari and Chrome */ -} - -.q_steps_holder .step4 .circle_small { - transform:rotate(170deg); - -ms-transform:rotate(170deg); /* IE 9 */ - -webkit-transform:rotate(170deg); /* Safari and Chrome */ -} - - -.q_steps_holder .step4{ - -webkit-transition-delay: 2s; - -moz-transition-delay: 2s; - -ms-transition-delay: 2s; - -o-transition-delay: 2s; - transition-delay: 2s; -} - -/* ========================================================================== - Steps shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Separator with text shortcode start styles - ========================================================================== */ -.vc_text_separator.full{ - padding-bottom: 20px; - border-top: 1px solid #eaeaea; - margin-top: 20px; - border-bottom:0; -} -.vc_text_separator.full.separator_align_center{ - text-align: center; -} -.vc_text_separator.full.separator_align_right{ - text-align: right; -} -.vc_text_separator.full div{ - padding: 0px 35px; - line-height: 36px; - top: -19px; - font-size: 12px; - color: #fff; - font-weight: 700; - background-color: #1abc9c; - border-radius: 2px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - -o-border-radius: 2px; - border:1px solid transparent; - display: inline-block; - position: relative; -} - -/* ========================================================================== - Separator with text shortcode end styles - ========================================================================== */ - -/* ========================================================================== - Separator with icon shortcode start styles - ========================================================================== */ -.separator_with_icon { - color: #818181; - display: block; - font-size: 18px; - line-height: 21px; - margin: 0 auto; - position: relative; - width: 783px; - max-width: 100%; - text-align: center; -} - -.separator_with_icon:before { - border-bottom: 1px solid #818181; - border-color: inherit; - content: ""; - display: inline-block; - left: 0; - position: absolute; - top: 10px; - width: 376px; -} - -.separator_with_icon:after { - border-bottom: 1px solid #818181; - border-color: inherit; - content: ""; - display: inline-block; - position: absolute; - right: 0; - top: 10px; - width: 376px; -} - -@media only screen and (max-width: 1000px){ - .separator_with_icon:after, - .separator_with_icon:before { - max-width: 45%; - } -} - -/* ========================================================================== - Separator with icon shortcode end styles - ========================================================================== */ - -.page_not_found { - text-align:center; - margin:0 0 83px; -} - -.page_not_found h2{ - margin: 40px 0 20px; - font-size:32px; -} -.page_not_found p{ - margin: 15px 0 35px; -} -.custom_font_holder{ - display: block; - position: relative; -} - - - -body div.pp_default .pp_loaderIcon{ - background-color: #ffffff; - border-radius: 20px; -} - -/* ========================================================================== - Pretty Photo style start - ========================================================================== */ - -div.pp_default .pp_top,div.pp_default .pp_top .pp_middle,div.pp_default .pp_top .pp_left,div.pp_default .pp_top .pp_right,div.pp_default .pp_bottom,div.pp_default .pp_bottom .pp_left,div.pp_default .pp_bottom .pp_middle,div.pp_default .pp_bottom .pp_right{height:13px} -div.pp_default .pp_top .pp_left{background:url(img/prettyPhoto/sprite.png) -78px -93px no-repeat} -div.pp_default .pp_top .pp_middle{background:url(img/prettyPhoto/sprite_x.png) top left repeat-x} -div.pp_default .pp_top .pp_right{background:url(img/prettyPhoto/sprite.png) -112px -93px no-repeat} -div.pp_default .pp_content .ppt{color:#f8f8f8} -div.pp_default .pp_content_container .pp_left{background:url(img/prettyPhoto/sprite_y.png) -7px 0 repeat-y;padding-left:13px} -div.pp_default .pp_content_container .pp_right{background:url(img/prettyPhoto/sprite_y.png) top right repeat-y;padding-right:13px} -div.pp_default .pp_next:hover{background:url(img/prettyPhoto/sprite_next.png) center right no-repeat;cursor:pointer} -div.pp_default .pp_previous:hover{background:url(img/prettyPhoto/sprite_prev.png) center left no-repeat;cursor:pointer} -div.pp_default .pp_expand{background:url(img/prettyPhoto/sprite.png) 0 -29px no-repeat;cursor:pointer;width:28px;height:28px} -div.pp_default .pp_expand:hover{background:url(img/prettyPhoto/sprite.png) 0 -56px no-repeat;cursor:pointer} -div.pp_default .pp_contract{background:url(img/prettyPhoto/sprite.png) 0 -84px no-repeat;cursor:pointer;width:28px;height:28px} -div.pp_default .pp_contract:hover{background:url(img/prettyPhoto/sprite.png) 0 -113px no-repeat;cursor:pointer} -div.pp_default .pp_close{width:30px;height:30px;background:url(img/prettyPhoto/sprite.png) 2px 1px no-repeat;cursor:pointer} -div.pp_default .pp_gallery ul li a{background:url(img/prettyPhoto/default_thumb.png) center center #f8f8f8;border:1px solid #aaa} -div.pp_default .pp_social{margin-top:7px} -div.pp_default .pp_gallery a.pp_arrow_previous,div.pp_default .pp_gallery a.pp_arrow_next{position:static;left:auto} -div.pp_default .pp_nav .pp_play,div.pp_default .pp_nav .pp_pause{background:url(img/prettyPhoto/sprite.png) -51px 1px no-repeat;height:30px;width:30px} -div.pp_default .pp_nav .pp_pause{background-position:-51px -29px} -div.pp_default a.pp_arrow_previous,div.pp_default a.pp_arrow_next{background:url(img/prettyPhoto/sprite.png) -31px -3px no-repeat;height:20px;width:20px;margin:4px 0 0} -div.pp_default a.pp_arrow_next{left:52px;background-position:-82px -3px} -div.pp_default .pp_content_container .pp_details{margin-top:5px} -div.pp_default .pp_nav{clear:none;height:30px;width:110px;position:relative} -div.pp_default .pp_nav .currentTextHolder{font-family:inherit;color:#999;font-size:13px;left:65px;line-height:25px;position:absolute;top:2px;margin:0;padding:0 0 0 10px} -div.pp_default .pp_close:hover,div.pp_default .pp_nav .pp_play:hover,div.pp_default .pp_nav .pp_pause:hover,div.pp_default .pp_arrow_next:hover,div.pp_default .pp_arrow_previous:hover{opacity:0.7} -div.pp_default .pp_description{font-size:15px;font-weight:300;line-height:14px;margin:10px 50px 10px 0} -div.pp_default .pp_bottom .pp_left{background:url(img/prettyPhoto/sprite.png) -78px -127px no-repeat} -div.pp_default .pp_bottom .pp_middle{background:url(img/prettyPhoto/sprite_x.png) bottom left repeat-x} -div.pp_default .pp_bottom .pp_right{background:url(img/prettyPhoto/sprite.png) -112px -127px no-repeat} -div.pp_default .pp_loaderIcon{background:url(img/prettyPhoto/loader.gif) center center no-repeat} -div.pp_pic_holder a:focus{outline:none} -div.pp_overlay{background-color:#000;display:none;left:0;position:absolute;top:0;width:100%;z-index:9500} -div.pp_pic_holder{display:none;position:absolute;width:100px;z-index:10000} -.pp_content{height:40px;min-width:40px} -* html .pp_content{width:40px} -.pp_content_container{position:relative;text-align:left;width:100%} -.pp_content_container .pp_left{padding-left:20px} -.pp_content_container .pp_right{padding-right:20px} -.pp_content_container .pp_details{float:left;margin:10px 0 2px} -.pp_description{display:none;margin:0} -.pp_social{float:left;margin:0} -.pp_social .facebook{float:left;margin-left:5px;width:55px;overflow:hidden} -.pp_social .twitter{float:left} -.pp_nav{clear:right;float:left;margin:3px 10px 0 0} -.pp_nav p{float:left;white-space:nowrap;margin:2px 4px} -.pp_nav .pp_play,.pp_nav .pp_pause{float:left;margin-right:4px;text-indent:-10000px} -a.pp_arrow_previous,a.pp_arrow_next{display:block;float:left;height:15px;margin-top:3px;overflow:hidden;text-indent:-10000px;width:14px} -.pp_hoverContainer{position:absolute;top:0;width:100%;z-index:2000} -.pp_gallery{display:none;left:50%;margin-top:-50px;position:absolute;z-index:10000} -.pp_gallery div{float:left;overflow:hidden;position:relative} -.pp_gallery ul{float:left;height:35px;position:relative;white-space:nowrap;margin:0 0 0 5px;padding:0} -.pp_gallery ul a{border:1px rgba(0,0,0,0.5) solid;display:block;float:left;height:33px;overflow:hidden} -.pp_gallery ul a img{border:0} -.pp_gallery li{display:block;float:left;margin:0 5px 0 0;padding:0} -.pp_gallery li.default a{background:url(../images/prettyPhoto/facebook/default_thumbnail.gif) 0 0 no-repeat;display:block;height:33px;width:50px} -.pp_gallery .pp_arrow_previous,.pp_gallery .pp_arrow_next{margin-top:7px!important} -a.pp_next{display:block;float:right;height:100%;text-indent:-10000px;width:49%} -a.pp_previous{display:block;float:left;height:100%;text-indent:-10000px;width:49%} -a.pp_expand,a.pp_contract{cursor:pointer;display:none;height:20px;position:absolute;right:30px;text-indent:-10000px;top:10px;width:20px;z-index:20000} -a.pp_close{position:absolute;right:0;top:0;display:block;line-height:22px;text-indent:-10000px} -.pp_loaderIcon{display:block;height:24px;left:50%;position:absolute;top:50%;width:24px;margin:-12px 0 0 -12px} -#pp_full_res{line-height:1!important} -#pp_full_res .pp_inline{text-align:left} -#pp_full_res .pp_inline p{margin:0 0 15px} -div.ppt{color:#fff;display:none;font-size:17px;z-index:9999;margin:0 0 5px 15px} -div.pp_default .pp_content{background-color:#fff} -div.pp_default #pp_full_res .pp_inline{color:#000} -div.pp_default .pp_gallery ul li a:hover,div.pp_default .pp_gallery ul li.selected a,.pp_gallery ul a:hover,.pp_gallery li.selected a{border-color:#fff} -div.pp_default .pp_details{position:relative} -.pp_top,.pp_bottom{height:20px;position:relative} -* html .pp_top,* html .pp_bottom{padding:0 20px} -.pp_top .pp_left,.pp_bottom .pp_left{height:20px;left:0;position:absolute;width:20px} -.pp_top .pp_middle,.pp_bottom .pp_middle{height:20px;left:20px;position:absolute;right:20px} -* html .pp_top .pp_middle,* html .pp_bottom .pp_middle{left:0;position:static} -.pp_top .pp_right,.pp_bottom .pp_right{height:20px;left:auto;position:absolute;right:0;top:0;width:20px} -.pp_fade,.pp_gallery li.default a img{display:none} - -body div.pp_overlay{ - opacity: 0.7 !important; -} - -body div.pp_default .pp_content_container .pp_left{background: none; padding: 0px;} -body div.pp_default .pp_content_container .pp_right{background: none; padding: 0px;} -body div.pp_default .pp_top, -body div.pp_default .pp_top .pp_middle, -body div.pp_default .pp_top .pp_left, -body div.pp_default .pp_top .pp_right, -body div.pp_default .pp_bottom, -body div.pp_default .pp_bottom .pp_left, -body div.pp_default .pp_bottom .pp_middle, -body div.pp_default .pp_bottom .pp_right{ - background: none; - display: none; -} - -body div.pp_default .pp_expand{ - display: none !important; -} - -body div.pp_default .pp_content{ - background: none; -} - -body a.pp_next, -body a.pp_previous{ - background: none !important; - opacity: 0; - -webkit-transition: opacity 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out; - -ms-transition: opacity 0.3s ease-in-out; - -o-transition: opacity 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out; -} - -body div.pp_default .pp_content:hover a.pp_next, -body div.pp_default .pp_content:hover a.pp_previous{ - opacity: 1; -} - -body a.pp_next:after { - border: 2px solid #FFFFFF; - border-radius: 50px; - color: #FFFFFF; - content: "\f105"; - display: block !important; - font-family: 'FontAwesome',serif; - font-size: 30px; - height: 54px; - line-height: 54px; - margin: -27px 0 0; - position: absolute; - right: 25px; - text-align: center; - top: 50%; - width: 54px; - text-indent: 0px; -} - -body a.pp_previous:after { - border: 2px solid #FFFFFF; - border-radius: 50px; - color: #FFFFFF; - content: "\f104"; - display: block !important; - font-family: 'FontAwesome',serif; - font-size: 30px; - height: 54px; - line-height: 54px; - margin: -27px 0 0; - position: absolute; - left: 25px; - text-align: center; - top: 50%; - width: 54px; - text-indent: 0px; -} - -body div.pp_default .pp_content_container .pp_details{ - opacity: 0.7; -} - -body div.pp_default .pp_description{ - display: none !important; -} - -body div.pp_default .pp_nav{ - float: none; - width: auto; - margin: 0px; -} - -body div.pp_default .pp_nav .currentTextHolder{ - left: auto; - position: relative; - float: left; - padding: 0px 20px; - font-family: 'Raleway', sans-serif; - font-size: 15px; - color: #ffffff; - font-weight: 600; -} - -body .pp_gallery{ - display: none !important; -} - -body div.pp_default .pp_nav .pp_play, -body div.pp_default .pp_nav .pp_pause{ - display: none; -} - -body div.pp_default a.pp_arrow_previous, -body div.pp_default a.pp_arrow_next{ - background: none; - position: relative; - left: 0px; -} - -body div.pp_default a.pp_arrow_previous:after{ - color: #FFFFFF; - content: "\f104"; - font-family: 'FontAwesome',serif; - font-size: 20px; - height: 20px; - line-height: 20px; - text-align: center; - width: 20px; - text-indent: 0px; - position: absolute; - top: 0px; - left: 0px; -} - -body div.pp_default a.pp_arrow_next:after{ - color: #FFFFFF; - content: "\f105"; - font-family: 'FontAwesome',serif; - font-size: 20px; - height: 20px; - line-height: 20px; - text-align: center; - width: 20px; - text-indent: 0px; - position: absolute; - top: 0px; - right: 0px; -} - -body div.pp_default .pp_close{ - background: none; - opacity: 1 !important; -} - -body div.pp_default .pp_close:after{ - color: #FFFFFF; - content: "\f00d"; - font-family: 'FontAwesome',serif; - font-size: 15px; - height: 15px; - line-height: 30px; - text-align: center; - width: 30px; - text-indent: 0px; - position: absolute; - top: 0px; - left: 0px; -} - -/* ========================================================================== - Pretty Photo style end - ========================================================================== */ - - -/**** Audio css ****/ - -.mejs-container { - position: relative; - text-align: left; - vertical-align: top; - text-indent: 0; - height: 40px !important; - border-radius: 4px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - background-color:#fff; -} -.mejs-container.wp-audio-shortcode { - height: 30px !important; - border-radius: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; -} -.blog_holder.masonry .mejs-container { - border:none; -} -.blog_holder.small_images article .post_text .post_inner .mejs-container{ - margin: 0 0 15px; -} - -.me-plugin { - position: absolute; -} - -.mejs-embed, .mejs-embed body { - width: 100%; - height: 100%; - margin: 0; - padding: 0; - overflow: hidden; -} - -.mejs-fullscreen { - /* set it to not show scroll bars so 100% will work */ - overflow: hidden !important; -} - -.mejs-container-fullscreen { - position: fixed; - left: 0; - top: 0; - right: 0; - bottom: 0; - overflow: hidden; - z-index: 1000; -} -.mejs-container-fullscreen .mejs-mediaelement, -.mejs-container-fullscreen video { - width: 100%; - height: 100%; -} - -.mejs-clear { - clear: both; -} - -/* Start: LAYERS */ -.mejs-background { - position: absolute; - top: 0; - left: 0; -} - -.mejs-mediaelement { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - -webkit-border-radius:4px; - -moz-border-radius:4px; - border-radius:4px; -} -.blog_holder.masonry .mejs-mediaelement{ - border: none; -} - -.mejs-poster { - position: absolute; - top: 0; - left: 0; - background-size: contain; - background-position: 50% 50% ; - background-repeat: no-repeat ; -} -:root .mejs-poster img { - display: none ; -} - -.mejs-poster img { - border: 0; - padding: 0; - border: 0; -} - -.mejs-overlay { - position: absolute; - top: 0; - left: 0; -} - -.mejs-overlay-play { - cursor: pointer; -} - -/* End: LAYERS */ - -/* Start: CONTROL BAR */ -.mejs-container .mejs-controls { - position: absolute; - list-style-type: none; - margin: 0; - padding: 0; - bottom: 0; - left: 0; - height: 40px; - width: 100%; -} -.mejs-container .mejs-controls div{ - list-style-type: none; - background-image: none; - display: block; - float: left; - margin: 0; - padding: 0; - width: 35px; - height: 40px; - border: 0; -} - -.mejs-controls .mejs-button button { - cursor: pointer; - display: block; - font-size: 0; - line-height: 0; - text-decoration: none; - margin: 14px 15px 13px 15px; - padding: 0; - position: absolute; - width: 12px; - height: 13px; - border: 0; - background: transparent; -} - -.no-svg .mejs-controls .mejs-button button { - background-image: url(img/audio/controls.png); -} - -/* :focus for accessibility */ -.mejs-controls .mejs-button button:focus { - outline: none; -} - -/* End: CONTROL BAR */ - -/* Start: Time (Current / Duration) */ -.mejs-container .mejs-controls .mejs-time { - color: #000; - display: block; - height: 40px; - width: auto; - padding: 0; - overflow: hidden; - text-align: center; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - box-sizing: content-box; -} - -.mejs-container .mejs-controls .mejs-time span { - color: #000; - font-size: 13px; - font-weight: 400; - line-height: 40px; - display: block; - float: left; - margin: 0; - width: auto; -} -/* End: Time (Current / Duration) */ - -/* Start: Play/Pause/Stop */ -.mejs-controls .mejs-play button { - background-image: url(img/audio/play.png); - background-repeat: no-repeat; - background-position: center; -} - -.mejs-controls .mejs-pause button { - background-image: url(img/audio/pause.png); - background-repeat: no-repeat; - background-position: center; -} - -.mejs-controls .mejs-stop button { - background-image: url(img/audio/stop.png); - background-repeat: no-repeat; - background-position: center; -} -/* Start: Play/Pause/Stop */ - -/* Start: Progress Bar */ -.mejs-controls div.mejs-time-rail { - direction: ltr; - width: 200px; -} - -.mejs-controls .mejs-time-rail span { - display: block; - position: absolute; - width: auto; - height: 8px; - margin: 16px 15px; - cursor: pointer; -} - -.mejs-controls .mejs-time-rail .mejs-time-total { - background-color: #dddddd; -} - -.mejs-controls .mejs-time-rail .mejs-time-buffering { - width: 100%; - background-image: -o-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(224, 222, 222, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(224, 222, 222, 0.15)), color-stop(0.75, rgba(224, 222, 222, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); - background-image: -ms-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); - -webkit-background-size: 15px 15px; - -moz-background-size: 15px 15px; - -o-background-size: 15px 15px; - background-size: 15px 15px; - -webkit-animation: buffering-stripes 2s linear infinite; - -moz-animation: buffering-stripes 2s linear infinite; - -ms-animation: buffering-stripes 2s linear infinite; - -o-animation: buffering-stripes 2s linear infinite; - animation: buffering-stripes 2s linear infinite; -} - -@-webkit-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } -@-moz-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } -@-ms-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } -@-o-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } -@keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } - -.mejs-controls .mejs-time-rail .mejs-time-loaded { - width: 0; - margin: 0px; -} - -.mejs-controls .mejs-time-rail .mejs-time-current { - background-color: #1abc9c; - margin: 0px; -} - -.mejs-controls .mejs-time-rail .mejs-time-handle { - display: none; - position: absolute; - margin: 0; - width: 10px; - background-color: #1abc9c; - cursor: pointer; - top: 0px; - text-align: center; -} - -.mejs-controls .mejs-time-rail .mejs-time-float { - position: absolute; - display: none; - width: 36px; - height: 15px; - top: -35px; - margin-left: -18px; - text-align: center; - color: #000; -} - -.mejs-controls .mejs-time-rail .mejs-time-float-current { - margin: 2px; - width: 30px; - display: block; - text-align: center; - left: 0; -} - -.mejs-controls .mejs-time-rail .mejs-time-float-corner { - display: none; -} - -.mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float { - width: 48px; -} - -.mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float-current { - width: 44px; -} - -.mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float-corner { - left: 18px; -} - -/* End: Progress Bar */ - -/* Start: Mute/Volume */ -.mejs-controls .mejs-volume-button { - background-image: url(img/audio/sound.png); - background-repeat: no-repeat; - background-position: center; -} - -.mejs-controls .mejs-mute button { - background-image: url(img/audio/sound.png); - background-repeat: no-repeat; - background-position: center; -} - -.mejs-controls .mejs-unmute button { - background-image: url(img/audio/mute.png); - background-repeat: no-repeat; - background-position: center; -} - -.mejs-controls .mejs-volume-button { - position: relative; -} - -.mejs-controls .mejs-volume-button button{ - width: 18px; - height: 16px; - margin: 12px 6px 12px 11px; -} - -.mejs-controls .mejs-volume-button .mejs-volume-slider { - display: none; - height: 115px; - width: 25px; - background-image: url(img/audio/sound.png); - background-repeat: no-repeat; - background-position: center; - top: -115px; - left: 0; - z-index: 1; - position: absolute; - margin: 0; -} - -.mejs-controls .mejs-volume-button .mejs-volume-slider .mejs-volume-total { - position: absolute; - left: 11px; - top: 8px; - width: 2px; - height: 100px; - margin: 0; -} - -.mejs-controls .mejs-volume-button .mejs-volume-slider .mejs-volume-current { - position: absolute; - left: 11px; - top: 8px; - width: 2px; - height: 100px; - margin: 0; -} - -.mejs-controls .mejs-volume-button .mejs-volume-slider .mejs-volume-handle { - position: absolute; - left: 4px; - top: -3px; - width: 16px; - height: 6px; - cursor: N-resize; - margin: 0; -} - -/* horizontal version */ -.mejs-controls div.mejs-horizontal-volume-slider { - height: 40px; - width: 45px; - position: relative; -} - -.mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total { - position: absolute; - left: 0; - top: 16px; - width: 35px; - height: 8px; - margin: 0; - padding: 0; - font-size: 1px; - background-color: #dddddd; -} - -.mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current { - position: absolute; - left: 0; - top: 16px; - width: 40px; - height: 8px; - margin: 0; - padding: 0; - font-size: 1px; - background-color: #1abc9c; -} - -.mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-handle { - display: none; -} - -/* End: Mute/Volume */ - -/* Start: Error */ -.me-cannotplay { -} - -.me-cannotplay a { - color: #fff; - font-weight: bold; -} - -.me-cannotplay span { - padding: 15px; - display: block; -} -/* End: Error */ - - -/* Start: Loop */ -.mejs-controls .mejs-loop-off button { - background-position: -64px -16px; -} - -.mejs-controls .mejs-loop-on button { - background-position: -64px 0; -} - -/* End: Loop */ - -/* Start: backlight */ -.mejs-controls .mejs-backlight-off button { - background-position: -80px -16px; -} - -.mejs-controls .mejs-backlight-on button { - background-position: -80px 0; -} -/* End: backlight */ - -/* ========================================================================== - Pie full styles - ========================================================================== */ - -.q_pie_graf_holder, -.q_line_graf_holder { - display: block; - position: relative; - overflow: hidden; -} - -.q_pie_graf, -.q_line_graf{ - margin: 0 22px 0 0; - float: left; -} - -.q_pie_graf_legend{ - position: relative; - float: left; - width: 40%; -} - -.q_line_graf_legend{ - position: relative; - float: left; - width: 20%; -} - -.q_pie_graf_legend ul, -.q_line_graf_legend ul{ - list-style: none; - padding:0; -} - -.q_pie_graf_legend ul li, -.q_line_graf_legend ul li{ - display: block; - margin: 0 0 10px 0; -} - -.q_pie_graf_legend ul li .color_holder, -.q_line_graf_legend ul li .color_holder{ - width: 25px; - height: 25px; - background-color: #1abc9c; - float: left; -} - -.q_pie_graf_legend ul li p, -.q_line_graf_legend ul li p{ - line-height: 25px; - margin: 0; - padding: 0 0 0 50px; -} - -/* ========================================================================== - WPML styles - ========================================================================== */ -.header_top .right #lang_sel ul ul img.iclflag, -.header_top .right #lang_sel_click ul ul img.iclflag { - float: right; - top: 11px; - margin-right: 0; - margin-left: 15px; -} - -.header_top .left #lang_sel ul ul img.iclflag, -.header_top .left #lang_sel_click ul ul img.iclflag { - float: left; - top: 11px; -} - -.header_top .right #lang_sel ul ul, -.header_top .right #lang_sel_click ul ul { - left: auto; - right: 0; -} - -.header_top #lang_sel_click ul ul{ - padding: 5px 15px !important; -} - -.header_top .right #lang_sel ul ul li , -.header_top .right #lang_sel_click ul ul li { - width: 100%; - text-align: right; -} - -.header_top .left #lang_sel ul ul li , -.header_top .left #lang_sel_click ul ul li { - width: 100%; -} - -.header_top #lang_sel ul ul li img.iclflag, -.header_top #lang_sel_click ul ul li img.iclflag { - position: relative; - top: 11px; -} - -.header_top #lang_sel li, -.header_top #lang_sel_click li { - width: auto; -} - -.header_top #lang_sel, .header_top #lang_sel_click { - font-family: inherit; - float: left; - padding: 0 0 0 0px; - z-index: 1000; - height: 33px; - position: relative; -} - -.header_top #lang_sel ul > li > a, -.header_top #lang_sel_click ul > li > a { - width: auto; - float: none; - padding: 0 15px !important; -} - -.header_top #lang_sel > ul > li:hover, -.header_top #lang_sel_click > ul > li:hover { - border-bottom: none !important; -} - -.header_top #lang_sel > ul > li > a, -.header_top #lang_sel_click > ul > li> a { - color: #777 !important; - line-height: 33px !important; - height: 33px; - z-index: 2500; - font-size:13px; -} - -.header_top #lang_sel > ul > li > a:hover, -.header_top #lang_sel_click > ul > li> a:hover{ - color: #1abc9c !important; -} - -.header_top .left #lang_sel > ul > li > a, -.header_top .left #lang_sel_click > ul > li> a { - left: 0; - right: auto; -} - -.header_top #lang_sel > ul > li > a:hover, -.header_top #lang_sel_click > ul > li> a:hover, -.header_top #lang_sel > ul > li:hover > a, -.header_top #lang_sel_click > ul > li:hover > a { - top: 0px; -} - -.header_top #lang_sel ul > li ul > li, -.header_top #lang_sel_click ul > li ul > li{ - padding:0px !important; -} - -.header_top #lang_sel ul > li a.lang_sel_sel, -.header_top #lang_sel_click ul > li a.lang_sel_sel { - background: 0; - line-height: 30px; - border: 0; - padding: 0; -} - -.header_top .right #lang_sel ul > li a.lang_sel_sel, -.header_top .right #lang_sel_click ul > li a.lang_sel_sel { - text-align: right; -} - -.header_top .right #lang_sel ul > li a.lang_sel_sel { - padding-right: 0 !important; -} - -.header_top .left #lang_sel ul > li a.lang_sel_sel { - padding-left: 0 !important; -} - -.header_top #lang_sel .lang_sel_sel:after, -.header_top #lang_sel_click .lang_sel_sel:after { - content: "\f107"; - font-family: 'FontAwesome', sans-serif; - margin-left: 5px; -} - -.header_top .left #lang_sel ul > li a.lang_sel_sel, -.header_top .left #lang_sel_click ul > li a.lang_sel_sel { - text-align: left; -} - -.header_bottom .main_menu .submenu-languages { - display: none; -} - -.header_top #lang_sel ul ul , -.header_top #lang_sel_click ul ul { - height: auto; - border-top: none; - background-color: #262626; - z-index:1000; - position:absolute; - list-style: none; - top: 33px; - left: -1px; - width: 180px; -} - -.header_top #lang_sel ul li ul li a, -.header_top #lang_sel ul li ul li a:visited, -.header_top #lang_sel_click ul li ul li a, -.header_top #lang_sel_click ul li ul li a:visited { - background: 0; - border: 0; - color: #9d9d9d; - display: block; - height: 38px; - white-space: nowrap; - font-weight: 600; - font-size: 11px; - text-transform: uppercase; - line-height: 38px; - padding: 0 15px !important; - border-bottom: 1px solid #303030; - - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - -.header_top #lang_sel ul li ul li:last-child a, -.header_top #lang_sel_click ul li ul li:last-child a{ - border-bottom: none; -} - -.header_top #lang_sel ul li ul li a:hover, -.header_top #lang_sel_click ul li ul li a:hover{ - color: #fff; -} - -.header_top #lang_sel_list { - font-family: inherit; - height: auto; - width: auto; - float: left; -} - -.header_top #lang_sel_list ul { - border: 0; - padding: 0 !important; - width: auto; -} - -.header_top #lang_sel_list li { - display: inline-block; - float: none; - width: auto; -} - -.header_top #lang_sel_list ul li a, -.header_top #lang_sel_list ul li a:visited { - padding: 0 8px 0 8px; - border: 0; - background: none repeat scroll 0 0 transparent; - line-height: 33px; - font-size: 13px; - color: #818181; - margin: 0 !important; - - -webkit-transition: color 0.3s ease-in-out; - -moz-transition: color 0.3s ease-in-out; - -ms-transition: color 0.3s ease-in-out; - -o-transition: color 0.3s ease-in-out; - transition: color 0.3s ease-in-out; -} - -.header_top #lang_sel_list ul li a.lang_sel_sel, -.header_top #lang_sel_list ul li a:hover{ - color: #1abc9c; -} - -.header_top #lang_sel img.iclflag, -.header_top #lang_sel_click img.iclflag, -.header_top #lang_sel_list img.iclflag { - display: inline; - float: none; - top: 1px; - position: relative; - margin-right: 5px; -} - -aside .widget.posts_holder #lang_sel li:after, -aside .widget.posts_holder #lang_sel_click li:after{ - content:none; -} - -aside .widget #lang_sel_list, -section.side_menu #lang_sel_list, -footer #lang_sel_list { - height: auto; - font-family: inherit; - width:100%; -} - -aside .widget #lang_sel_list li, -section.side_menu #lang_sel_list li, -footer #lang_sel_list li{ - float: none; - margin-bottom: 0px !important; - padding: 9px 10px 9px 0px !important; - width:auto; -} - -footer #lang_sel_list li{ - padding: 5px 5px 5px 0px !important; -} - -aside .widget #lang_sel_list li a, -aside .widget #lang_sel li a, -aside .widget #lang_sel_click li a, -section.side_menu #lang_sel_list li a, -section.side_menu #lang_sel li a, -section.side_menu #lang_sel_click li a, -footer #lang_sel_list li a, -footer #lang_sel li a, -footer #lang_sel_click li a { - font-family: inherit; - font-size: 13px; - font-weight: 400; - border: 0; - color: #777; -} - -aside .widget #lang_sel_list li a, -section.side_menu #lang_sel_list li a, -aside .widget #lang_sel_list li a, -footer #lang_sel_list li a { - display: inline; -} - -aside .widget #lang_sel li, -aside .widget #lang_sel_click li, -section.side_menu #lang_sel li, -section.side_menu #lang_sel_click li, -footer #lang_sel li, -footer #lang_sel_click li { - margin-bottom: 0; -} - -aside .widget #lang_sel, -aside .widget #lang_sel_click, -section.side_menu #lang_sel, -section.side_menu #lang_sel_click, -footer #lang_sel, -footer #lang_sel_click { - width: 100%; -} - -aside .widget #lang_sel > ul > li > a, -aside .widget #lang_sel_click > ul > li > a, -section.side_menu #lang_sel > ul > li > a, -section.side_menu #lang_sel_click > ul > li > a, -footer #lang_sel > ul > li > a, -footer #lang_sel_click > ul > li > a { - height: 35px; - line-height: 35px !important; - font-family: inherit; - font-weight: 300; - padding-left: 13px; - font-weight: 300; - background-image: url(img/wc_select_arrow.png) !important; - background-repeat: no-repeat; - background-position: right; -} - -footer #lang_sel > ul > li > a, -footer #lang_sel_click > ul > li > a, -section.side_menu #lang_sel > ul > li > a, -section.side_menu #lang_sel_click > ul > li > a { - background-image: url(img/wc_select_arrow_footer.png) !important; - background-repeat: no-repeat; - background-position: right; -} - -aside .widget #lang_sel > ul > li a, -aside .widget #lang_sel_click > ul > li a{ - background-color: #fff; -} - -footer #lang_sel > ul > li a, -footer #lang_sel_click > ul > li a, -section.side_menu #lang_sel > ul > li a, -section.side_menu #lang_sel_click > ul > li a{ - background-color: #262626 !important; -} - -footer #lang_sel ul li a, -footer #lang_sel ul ul a, -footer #lang_sel_click ul li a, -footer #lang_sel_click ul ul a, -footer #lang_sel_click ul ul a span, -section.side_menu #lang_sel ul li a, -section.side_menu #lang_sel ul ul a, -section.side_menu #lang_sel ul ul a:visited, -section.side_menu #lang_sel_click > ul > li > a, -section.side_menu #lang_sel_click ul ul a, -section.side_menu #lang_sel_click ul ul a:visited{ - color: #777 !important; -} - -aside .widget #lang_sel > ul li a, -aside .widget #lang_sel ul ul a, -aside .widget #lang_sel_click > ul li a, -aside .widget #lang_sel_click ul ul a, -aside .widget #lang_sel_list li a{ - color: #adadad; - font-family: 'Raleway', sans-serif; - background-color: #fff; -} - -aside .widget #lang_sel a.lang_sel_sel:hover, -aside .widget #lang_sel_click a.lang_sel_sel:hover, -aside .widget #lang_sel ul ul a:hover, -aside .widget #lang_sel_click ul ul a:hover, -aside .widget #lang_sel_list li a.lang_sel_sel, -aside .widget #lang_sel_list li a:hover{ - color: #1abc9c; -} - -footer #lang_sel_list li a:hover, -footer #lang_sel a.lang_sel_sel, -footer #lang_sel a.lang_sel_sel:hover, -footer #lang_sel ul ul a:hover, -footer #lang_sel_click a.lang_sel_sel, -footer #lang_sel_click ul ul a:hover, -footer #lang_sel_click ul ul a:hover span, -footer #lang_sel_list a.lang_sel_sel, -footer #lang_sel_list ul ul a:hover, -footer #lang_sel_list ul ul a:hover span, -section.side_menu a.lang_sel_sel, -section.side_menu #lang_sel ul li a.lang_sel_sel, -section.side_menu #lang_sel_click ul li a.lang_sel_sel, -section.side_menu #lang_sel_list li a:hover, -section.side_menu #lang_sel ul ul a:hover, -section.side_menu #lang_sel_click ul ul a:hover, -section.side_menu #lang_sel_click ul ul a:hover span{ - color: #fff !important; -} - -aside .widget #lang_sel li, -aside .widget #lang_sel_click li, -section.side_menu #lang_sel li, -section.side_menu #lang_sel_click li, -footer #lang_sel li, -footer #lang_sel_click li { - width: 100%; - padding:0; - border:none; -} - -aside .widget #lang_sel ul ul, -aside .widget #lang_sel_click ul ul{ - width: 100%; - top:32px; - height: auto; - border: 0; - z-index: 1000; - padding:3px 0 0 0; - overflow:hidden; -} - -footer #lang_sel ul ul, -footer #lang_sel_click ul ul , -section.side_menu #lang_sel ul ul, -section.side_menu #lang_sel_click ul ul{ - width: 100%; - top:32px; - border: 0; -} - -section.side_menu #lang_sel li a:after, -section.side_menu #lang_sel li:before{ - display:none; -} - -section.side_menu #lang_sel ul ul a, #lang_sel ul ul a:visited{ - padding: 8px 10px; -} - -footer #lang_sel ul ul, -footer #lang_sel_click ul ul, -section.side_menu #lang_selul ul, -section.side_menu #lang_sel_click ul ul { - left: 0 !important; -} - -aside .widget #lang_sel ul ul a, -aside .widget #lang_sel_click ul ul a, -aside .widget #lang_sel ul ul a:visited, -aside .widget #lang_sel_click ul ul a:visited{ - padding: 10px 13px; -} - -footer #lang_sel ul ul a, -footer #lang_sel_click ul ul a, -footer #lang_sel ul ul a:visited, -footer #lang_sel_click ul ul a:visited{ - padding: 10px 13px; -} - -aside .widget #lang_sel_list.lang_sel_list_vertical ul, -section.side_menu #lang_sel_list.lang_sel_list_vertical ul, -footer #lang_sel_list.lang_sel_list_vertical ul { - height: auto; - border-top: none; -} - -aside .widget #lang_sel_list.lang_sel_list_vertical a, -aside .widget #lang_sel_list.lang_sel_list_vertical a:visited, -section.side_menu #lang_sel_list.lang_sel_list_vertical a, -section.side_menu #lang_sel_list.lang_sel_list_vertical a:visited, -footer #lang_sel_list.lang_sel_list_vertical a, -footer #lang_sel_list.lang_sel_list_vertical a:visited { - border: none; - padding: 0; -} - -section.side_menu #lang_sel_list.lang_sel_list_vertical a, -section.side_menu #lang_sel_list.lang_sel_list_vertical a:visited, -section.side_menu #lang_sel_list.lang_sel_list_horizontal a, -section.side_menu #lang_sel_list.lang_sel_list_horizontal a:visited, -footer #lang_sel_list.lang_sel_list_vertical a, -footer #lang_sel_list.lang_sel_list_vertical a:visited, -footer #lang_sel_list.lang_sel_list_horizontal a, -footer #lang_sel_list.lang_sel_list_horizontal a:visited { - background: transparent; -} - -aside #lang_sel img.iclflag, -aside #lang_sel_click img.iclflag, -section.side_menu #lang_sel img.iclflag, -section.side_menu #lang_sel_click img.iclflag, -footer #lang_sel img.iclflag, -footer #lang_sel_click img.iclflag, -footer #lang_sel_list.lang_sel_list_horizontal a img, -footer #lang_sel_list.lang_sel_list_vertical a img { - margin-right: 5px; -} - -footer #lang_sel_list.lang_sel_list_horizontal a:hover, -footer #lang_sel_list.lang_sel_list_vertical a:hover, -.side_menu #lang_sel_list.lang_sel_list_horizontal a:hover, -.side_menu #lang_sel_list.lang_sel_list_vertical a:hover { - color: #fff; -} - -footer #lang_sel_list.lang_sel_list_horizontal a, -footer #lang_sel_list.lang_sel_list_vertical a, -.side_menu #lang_sel_list.lang_sel_list_horizontal a, -.side_menu #lang_sel_list.lang_sel_list_vertical a { - color: #777; -} - -#lang_sel_footer { - background-color: #111111; - border: none; - z-index: 1500; - position: relative; - font-family: 'Roboto', sans-serif; -} - -#lang_sel_footer a { - font-size: 13px; - color: #777; - -webkit-transition: color 0.3s ease 0s !important; - -moz-transition: color 0.3s ease 0s !important; - -o-transition: color 0.3s ease 0s !important; - -ms-transition: color 0.3s ease 0s !important; - transition: color 0.3s ease 0s !important; -} - -#lang_sel_footer a:hover { - color: #fff; - -webkit-transition: color 0.3s ease 0s !important; - -moz-transition: color 0.3s ease 0s !important; - -o-transition: color 0.3s ease 0s !important; - -ms-transition: color 0.3s ease 0s !important; - transition: color 0.3s ease 0s !important; -} - -#lang_sel_footer a img { - margin-right: 15px; -} - -/* ========================================================================== - End of WPML styles - ========================================================================== */ - -.ls-nav-prev, -.ls-nav-next { - position: absolute; - display: block !important; - line-height: 40px; - margin: -20px 0 0; - top: 60%; - z-index: 90; - cursor: pointer; - opacity: 0.6 !important; - filter: alpha(opacity=60) !important; -} - -.ls-nav-prev{ - background-image:none !important; - background-color: transparent !important; - height: 54px; - width: 54px; - border: 2px solid #fff !important; - line-height: 54px; - font-size: 14px; - position: absolute; - top: 50%; - margin-top: -27px; - text-align: center; - z-index: 10; - -webkit-transition: opacity .3s ease 0s !important; - -moz-transition: opacity .3s ease 0s !important; - -o-transition: opacity .3s ease 0s !important; - transition: opacity .3s ease-in-out !important; - opacity: 0.7; - -webkit-border-radius: 56px; - -moz-border-radius: 56px; - -ms-border-radius: 56px; - -o-border-radius: 56px; - border-radius: 56px; - position: absolute; - left: 23px; -} -.ls-nav-prev:after { - position: absolute; - left: 0 !important; - color: #fff; - width: 100%; - height: 100%; - content: "\f104"; - font-family: 'FontAwesome', serif; - line-height: 54px; - text-align:center; - display: block !important; - font-size:30px; -} -.ls-nav-next{ - background-image:none !important; - background-color: transparent !important; - height: 54px; - width: 54px; - border: 2px solid #fff !important; - line-height: 54px; - font-size: 14px; - position: absolute; - top: 50%; - margin-top: -27px; - text-align: center; - z-index: 10; - -webkit-transition: opacity .3s ease 0s; - -moz-transition: opacity .3s ease 0s; - -o-transition: opacity .3s ease 0s; - transition: opacity .3s ease-in-out; - opacity: 0; - -webkit-border-radius: 56px; - -moz-border-radius: 56px; - -ms-border-radius: 56px; - -o-border-radius: 56px; - border-radius: 56px; - right: 23px; -} -.ls-nav-next:after { - position: absolute; - left: 0 !important; - color: #fff; - width: 100%; - height: 100%; - content: "\f105"; - font-family: 'FontAwesome', serif; - line-height: 54px; - text-align:center; - display: block !important; - font-size:30px; -} - -.ls-nav-prev:hover, -.ls-nav-next:hover{ - opacity: 1 !important; - filter: alpha(opacity=100) !important; -} - -.element_from_left, -.element_from_right, -.element_from_top, -.element_from_bottom, -.element_from_fade{ - display: inline-block; - width: 100%; -} - -.touch .no_animation_on_touch .element_from_left>div, -.touch .no_animation_on_touch .element_from_right>div, -.touch .no_animation_on_touch .element_from_top>div, -.touch .no_animation_on_touch .element_from_bottom>div, -.touch .no_animation_on_touch .element_from_fade>div, -.touch .no_animation_on_touch .element_transform>div{ - opacity: 1; - filter: alpha(opacity = 100); - -webkit-transform: scale(1); - -moz-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); - -webkit-animation: none; - -moz-animation: none; - -o-animation: none; - animation: none; -} - -.element_from_left > div, -.element_from_right > div, -.element_from_top > div, -.element_from_bottom > div, -.element_from_fade > div { - opacity: 0; - display: inline-block; - width: 100%; - filter: alpha(opacity = 0); -} - -.element_transform > div{ - opacity: .2; - -webkit-transform: scale(0.5); - -moz-transform: scale(0.5); - -o-transform: scale(0.5); - transform: scale(0.5); -} - -.element_from_fade.element_from_fade_on > div { - opacity: 1; - filter: alpha(opacity = 100); - -webkit-transition: opacity .8s ease 0s; - -moz-transition: opacity .8s ease 0s; - -o-transition: opacity .8s ease 0s; - -webkit-backface-visibility: hidden; -} - -.element_from_left.element_from_left_on > div { - -webkit-animation: element-from-left 0.7s 1 ease-in-out; - -moz-animation: element-from-left 0.7s 1 ease-in-out; - -o-animation: element-from-left 0.7s 1 ease-in-out; - animation: element-from-left 0.7s 1 ease-in-out; - opacity: 1; - filter: alpha(opacity = 100); - -webkit-backface-visibility: hidden; -} - -.element_from_right.element_from_right_on>div { - -webkit-animation: element-from-right 0.7s 1 ease-in-out; - -moz-animation: element-from-right 0.7s 1 ease-in-out; - -o-animation: element-from-right 0.7s 1 ease-in-out; - animation: element-from-right 0.7s 1 ease-in-out; - opacity: 1; - filter: alpha(opacity = 100); - -webkit-backface-visibility: hidden; -} - -.element_from_top.element_from_top_on>div { - -webkit-animation: element-from-top 0.7s 1 ease-in-out; - -moz-animation: element-from-top 0.7s 1 ease-in-out; - -o-animation: element-from-top 0.7s 1 ease-in-out; - animation: element-from-top 0.7s 1 ease-in-out; - opacity: 1; - filter: alpha(opacity = 100); - -webkit-backface-visibility: hidden; -} - -.element_from_bottom.element_from_bottom_on>div { - -webkit-animation: element-from-bottom 0.7s 1 ease-in-out; - -moz-animation: element-from-bottom 0.7s 1 ease-in-out; - -o-animation: element-from-bottom 0.7s 1 ease-in-out; - animation: element-from-bottom 0.7s 1 ease-in-out; - opacity: 1; - filter: alpha(opacity = 100); - -webkit-backface-visibility: hidden; -} - -.element_transform.element_transform_on>div { - -webkit-animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); - -moz-animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); - -o-animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); - animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); - opacity: 1; - -webkit-transform: scale(1); - -moz-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); -} - -@-webkit-keyframes element-from-left { - 0% { - -webkit-transform: translate(-20%, 0); - opacity: 0; - } - 100% { - -webkit-transform: translate(0, 0); - opacity: 1; - } -} - -@-moz-keyframes element-from-left { - 0% { - -moz-transform: translate(-20%, 0); - opacity: 0; - } - 100% { - -moz-transform: translate(0, 0); - opacity: 1; - } -} - -@-o-keyframes element-from-left { - 0% { - -o-transform: translate(-20%, 0); - opacity: 0; - } - 100% { - -o-transform: translate(0, 0); - opacity: 1; - } -} - -@keyframes element-from-left { - 0% { - transform: translate(-20%, 0); - opacity: 0; - } - 100% { - transform: translate(0, 0); - opacity: 1; - } -} - -@-webkit-keyframes element-from-right { - 0% { - -webkit-transform: translate(20%, 0); - opacity: 0; - } - 100% { - -webkit-transform: translate(0, 0); - opacity: 1; - } -} - -@-moz-keyframes element-from-right { - 0% { - -moz-transform: translate(20%, 0); - opacity: 0; - } - 100% { - -moz-transform: translate(0, 0); - opacity: 1; - } -} - -@-o-keyframes element-from-right { - 0% { - -o-transform: translate(20%, 0); - opacity: 0; - } - 100% { - -o-transform: translate(0, 0); - opacity: 1; - } -} - -@keyframes element-from-right { - 0% { - transform: translate(20%, 0); - opacity: 0; - } - 100% { - transform: translate(0, 0); - opacity: 1; - } -} - -@-webkit-keyframes element-from-bottom { - 0% { - -webkit-transform: translate(0, 30%); - opacity: 0; - } - 100% { - -webkit-transform: translate(0, 0); - opacity: 1; - } -} - -@-moz-keyframes element-from-bottom { - 0% { - -moz-transform: translate(0, 30%); - opacity: 0; - } - 100% { - -moz-transform: translate(0, 0); - opacity: 1; - } -} - -@-o-keyframes element-from-bottom { - 0% { - -o-transform: translate(0, 30%); - opacity: 0; - } - 100% { - -o-transform: translate(0, 0); - opacity: 1; - } -} - -@keyframes element-from-bottom { - 0% { - transform: translate(0, 30%); - opacity: 0; - } - 100% { - transform: translate(0, 0); - opacity: 1; - } -} - -@-webkit-keyframes element-from-top { - 0% { - -webkit-transform: translate(0, -30%); - opacity: 0; - } - 100% { - -webkit-transform: translate(0, 0); - opacity: 1; - } -} - -@-moz-keyframes element-from-top { - 0% { - -moz-transform: translate(0, -30%); - opacity: 0; - } - 100% { - -moz-transform: translate(0, 0); - opacity: 1; - } -} - -@-o-keyframes element-from-top { - 0% { - -o-transform: translate(0, -30%); - opacity: 0; - } - 100% { - -o-transform: translate(0, 0); - opacity: 1; - } -} - -@keyframes element-from-top { - 0% { - transform: translate(0, -30%); - opacity: 0; - } - 100% { - transform: translate(0, 0); - opacity: 1; - } -} - -@-webkit-keyframes element-transform { - 0% { - -webkit-transform: scale(0.3); - opacity: .1; - } - 100% { - -webkit-transform: scale(1); - opacity: 1; - } -} - -@-moz-keyframes element-transform { - 0% { - -moz-transform: scale(0.3); - opacity: .1; - } - 100% { - -moz-transform: scale(1); - opacity: 1; - } -} - -@-o-keyframes element-transform { - 0% { - -o-transform: scale(0.3); - opacity: .1; - } - 100% { - -o-transform: scale(1); - opacity: 1; - } -} - -@keyframes element-transform { - 0% { - transform: scale(0.3); - opacity: .1; - } - 100% { - transform: scale(1); - opacity: 1; - } -} - -/* ========================================================================== - Image With Text Over start styles - ========================================================================== */ -.q_image_with_text_over{ - display: inline-block; - position: relative; - margin: 0px; - width: 100%; -} - -.q_image_with_text_over.one_half{ - width: 50%; -} - -.q_image_with_text_over.one_third{ - width: 33.33%; -} - -.q_image_with_text_over.one_fourth{ - width: 25%; -} - -.q_image_with_text_over img{ - display: block; - position: relative; - width: 100%; - z-index: 10; -} - -.q_image_with_text_over .shader{ - position: absolute; - width: 100%; - height: 100%; - top: 0px; - left: 0px; - z-index: 20; - background-color: rgba(0,0,0,0.5); -} - -.q_image_with_text_over .text{ - position: absolute; - width: 100%; - height: 100%; - top: 0px; - left: 0px; - z-index: 30; - text-align: center; -} - -.q_image_with_text_over table{ - position: absolute; - width: 100%; - height: 100%; - top: 0px; - left: 0px; - width: 100%; - height: 100%; -} - -.q_image_with_text_over table td{ - padding: 0px; - vertical-align: middle; - background: none !important; -} - -.q_image_with_text_over .caption, -.q_image_with_text_over .icon_holder{ - opacity: 1; - filter: alpha(opacity = 100); - -webkit-transition: opacity 0.4s ease-in-out; - -moz-transition: opacity 0.4s ease-in-out; - -o-transition: opacity 0.4s ease-in-out; - -ms-transition: opacity 0.4s ease-in-out; - -webkit-transform: translateZ(0px); -} - -.q_image_with_text_over .caption{ - line-height: 1em; -} - -.q_image_with_text_over .text p, -.q_image_with_text_over .caption, -.q_image_with_text_over .icon_holder{ - color: #fff; -} - -.q_image_with_text_over .icon_holder{ - display: inline-block; -} - -.q_image_with_text_over .icon_holder.fa-2x{ - padding: 0.67em 0.7em; -} - -.q_image_with_text_over .icon_holder.fa-3x{ - padding: 0.6em 0.62em; -} - -.q_image_with_text_over .caption{ - margin: 2% 0 0; -} - -.q_image_with_text_over .caption.no_icon{ - margin: 0; -} - -.q_image_with_text_over .desc{ - margin: 0px 30px; - opacity: 0; - filter: alpha(opacity = 0); - -webkit-transition: opacity 0.4s ease-in-out; - -moz-transition: opacity 0.4s ease-in-out; - -o-transition: opacity 0.4s ease-in-out; - -ms-transition: opacity 0.4s ease-in-out; - -webkit-backface-visibility:hidden; - -webkit-transform: translateZ(0px); - color:#fff; -} - -.q_image_with_text_over .text:hover .caption, -.q_image_with_text_over .text:hover .icon_holder{ - opacity: 0; - filter: alpha(opacity = 0); -} - -.q_image_with_text_over .text:hover .desc{ - opacity: 1; - filter: alpha(opacity = 100); -} -/* ========================================================================== - Image With Text Over end styles - ========================================================================== */ - -/* ========================================================================== - Team start styles - ========================================================================== */ - -.q_team{ - background-color:#fff; - overflow:hidden; - } - - .q_team_inner{ - overflow:hidden; - width: 100%; - } - -.q_team .q_team_image{ - position:relative; -} - -.q_team .q_team_image img{ - width:100%; - vertical-align: middle; -} - -.q_team .q_team_description_wrapper { - position: absolute; - top: 0; - width: 100%; - height: 100%; - background-color: rgba(255, 255, 255, 0.95); - opacity: 0; - -webkit-transition: opacity 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out; - -ms-transition: opacity 0.3s ease-in-out; - -o-transition: opacity 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out; - cursor: default; -} - -.q_team .q_team_image:hover .q_team_description_wrapper { - opacity: 1; -} - -.q_team .q_team_description { - display: table; - width: 100%; - height: 100%; -} - -.q_team .q_team_description_inner { - display: table-cell; - vertical-align: middle; - text-align: center; - padding: 0 50px; -} - -.q_team .q_team_description_inner p { - color: #303030; -} - -.q_team .q_team_text{ - padding:23px 16px 23px; - border-style: none; - border-width: 1px; - border-color: #f6f6f6; - border-top:none !important; -} - -.q_team .q_team_title_holder{ - margin: 0 0 9px; - text-align: center; -} -.q_team .q_team_title_holder .q_team_name{ - margin-bottom: 7px; -} -.q_team .q_team_text_inner .separator{ - background-color: #1abc9c; - margin-bottom: 16px !important; -} - -.q_team .q_team_social_holder{ - position: relative; - text-align: center; - -} -.q_team .q_team_social_holder .q_social_icon_holder i.simple_social{ - font-size: 19px; - color: #bcbcbc; -} - -.q_team .q_team_social_holder .q_social_icon_holder:hover i.simple_social { - color: #1abc9c; -} - -/*Info on hover style*/ - -.q_team.info_on_hover .q_team_description_wrapper{ - position: relative; - opacity: 1; - background-color: transparent; - box-sizing: border-box; -} - -.q_team.info_on_hover .q_team_text{ - position: absolute; - top: 0; - width: 100%; - height: 100%; - background-color: rgba(21, 21, 21, 0.78); - padding: 0; - opacity: 0; - -webkit-transition: opacity 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out; - -ms-transition: opacity 0.3s ease-in-out; - -o-transition: opacity 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out; -} - -.q_team.info_on_hover .q_team_text_holder{ - display: table; - width: 100%; - height: 100%; -} - -.q_team.info_on_hover .q_team_text_holder_inner{ - display: table-cell; - vertical-align: middle; -} - -.q_team.info_on_hover .q_team_image:hover .q_team_text{ - opacity: 1; -} - -.q_team.info_on_hover .q_team_title_holder .q_team_name, -.q_team.info_on_hover .q_team_title_holder span, -.q_team.info_on_hover .q_team_social_holder i.simple_social{ - color: #fff; -} - -/* ========================================================================== - Team end styles - ========================================================================== */ - - -/* ========================================================================== - Service shortcode styles - ========================================================================== */ -.circle_item .circle { - font-size: 15px; - line-height: 13px; - width: 155px; - height: 155px; - display: inline-block; - text-align: center; - color: #000; - background-color: #fbfbfb; - -o-border-radius: 182px; - -moz-border-radius: 182px; - -webkit-border-radius: 182px; - border-radius: 182px; - -webkit-transition: all .5s ease 0s; - -moz-transition: all .5s ease 0s; - -o-transition: all .5s ease 0s; - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); -} - -.circle_item .circle div { - padding: 69.5px 0; -} - -.circle_left { - width: 100%; - display: inline-block; - margin: 0 0 25px 0; -} - -.circle_left .circle { - float: left; -} - -.circle_left .text { - padding: 0 10px 0 170px; -} - -.circle_top { - width: 100%; - display: inline-block; - text-align: center; - margin: 0 0 25px 0; -} - -.circle_top .circle { - margin: 0 auto; -} - -.circle_top .text { - margin: 25px 0 0; -} - -.circle_top .text p { - margin: 0; -} - -.circle_item .circle a { - text-decoration: none; -} - -.circle_item .circle:hover { - background-color: #1abc9c; - color: #fff; -} - -.circle_item .circle.hover { - cursor: pointer; -} - -.circle_item .circle:hover a { - color: #fff; -} - -.fade_in_circle_holder { - display: block; - cursor: pointer; - overflow: hidden; -} - -.fade_in_circle_holder.animate_circle { - opacity: 1; - filter: alpha(opacity=100); - -webkit-transform: scale(1); - -moz-transform: scale(1); - -o-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); -} - -.fade_in_circle_holder { - display: table; - position: relative; - overflow: hidden; - opacity: 0; - filter: alpha(opacity=0); - -webkit-transform: scale(0.1); - -moz-transform: scale(0.1); - -o-transform: scale(0.1); - -ms-transform: scale(0.1); - -webkit-transition: all .4s ease-in-out; - -moz-transition: all .4s ease-in-out; - -o-transition: all .4s ease-in-out; - -ms-transition: all .4s ease-in-out; - transition: all .4s ease-in-out; - -webkit-backface-visibility: hidden; - z-index: 2000; -} - -.touch .no_animation_on_touch .fade_in_circle_holder{ - opacity: 1; - filter: alpha(opacity=100); - -webkit-transform: scale(1); - -moz-transform: scale(1); - -o-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); -} - -/* ========================================================================== - Image hover styles - ========================================================================== */ -.image_hover { - position: relative; - display: inline-block; - width: 100%; -} - -.image_hover .images_holder { - position: relative; - display: inline-block; -} - -.image_hover .images_holder img.hover_image { - position: absolute; - top: 0; - left: 0; -} - -.image_hover .images_holder img.active_image { - opacity: 1; - filter: alpha(opacity = 100); - position: relative; - display: block; -} - -.image_hover .images_holder img.active_image, -.image_hover .images_holder img.hover_image, -.image_hover.hovered.show .images_holder img.active_image, -.image_hover.hovered.show .images_holder img.hover_image { - -webkit-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -webkit-backface-visibility:hidden; - -webkit-transform: translateZ(0px); -} - -.image_hover .images_holder img.hover_image { - opacity: 0; - filter: alpha(opacity = 0); -} - -.image_hover .images_holder:hover img.active_image, -.image_hover.hovered.show .images_holder img.active_image { - opacity: 0; - filter: alpha(opacity = 0); -} - -.image_hover .images_holder:hover img.hover_image, -.image_hover.hovered.show .images_holder img.hover_image { - opacity: 1; - filter: alpha(opacity = 100); -} - -/* ========================================================================== - Call to action widget styles - ========================================================================== */ - -/*.content_bottom{ - position: relative; - z-index: 100; -}*/ - -.qode_call_to_action.container { - background-color: #1abc9c; -} - -.qode_call_to_action.in_grid { - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} - -.qode_call_to_action.container .container_inner { - padding: 40px 0; -} - -.call_to_action_text_wrapper p { - font-size: 19px; - font-weight: 300; - line-height: 1.692307692307692em; - color: #fff; - text-align: center; -} - -.qode_call_to_action .call_to_action_text_wrapper { - line-height: 40px; -} - -.qode_call_to_action .qbutton{ - position: static; -} - -.call_to_action_button_wrapper { - text-align: left; -} - -.call_to_action_button_wrapper.left { - text-align: left; -} - -.qode_call_to_action .two_columns_75_25>.column2.left>.column_inner { - padding: 0 20px 0 0; -} - -.qode_call_to_action.in_grid .two_columns_75_25>.column2.left>.column_inner { - padding-left: 28px; -} - -.qode_call_to_action.in_grid .two_columns_75_25>.column2>.column_inner { - padding-right: 28px; -} - -.qode_call_to_action.in_grid .two_columns_75_25>.column1.left>.column_inner { - padding-right: 28px; -} - -.qode_call_to_action.in_grid .two_columns_75_25>.column1>.column_inner { - padding-left: 28px; -} - -.qode_call_to_action .two_columns_75_25>.column1.left>.column_inner { - padding: 0; -} - -.qode_call_to_action .two_columns_75_25>.column1.left { - text-align: right; -} - -/* ========================================================================== - * Bootstrap v3.0.0 - * - * Copyright 2013 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world by @mdo and @fat. - * normalize.css v2.1.0 | MIT License | git.io/normalize - ========================================================================== */ -.carousel { - position: relative; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} - -.boxed .carousel-inner{ - width: 1150px; - left: auto !important; -} - -.carousel-inner .video{ - position: static; - left: 0; - direction: ltr; -} - -.carousel-inner > .item { - position: relative; - display: none; - -webkit-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} - -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - height: auto; - max-width: 100%; - line-height: 1; -} - -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} - -.carousel-inner > .active { - left: 0; -} - -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} - -.carousel-inner > .next { - left: 100%; -} - -.carousel-inner > .prev { - left: -100%; -} - -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} - -.carousel-inner > .active.left { - left: -100%; -} - -.carousel-inner > .active.right { - left: 100%; -} - -/* part for fading adnimation - start */ -.carousel.fade .item { - -webkit-transition: opacity 0.5s ease-in-out; - -moz-transition: opacity 0.5s ease-in-out; - -ms-transition: opacity 0.5s ease-in-out; - -o-transition: opacity 0.5s ease-in-out; - transition: opacity 0.5s ease-in-out; - opacity: 1; - filter: alpha(opacity=100); -} - -.carousel.fade .active.left, -.carousel.fade .active.right { - opacity: 0; - filter: alpha(opacity=0); -} - -.carousel.fade .active.item { - opacity: 1; - filter: alpha(opacity=100); -} - -.carousel.fade .active.left, -.carousel.fade .active.right { - left: 0; - z-index: 2; - opacity: 0; - filter: alpha(opacity=0); -} - -.carousel.fade .next, -.carousel.fade .prev { - left: 0; - z-index: 1; -} - -/* part for fading adnimation - end */ - -.carousel-indicators { - position: absolute; - bottom: 20px; - left: 50%; - z-index: 15; - width: 60%; - padding-left: 0; - margin-left: -30%; - text-align: center; - list-style: none; -} - -.carousel-indicators li { - display: inline-block; - width: 8px; - height: 8px; - margin: 1px; - text-indent: -999px; - cursor: pointer; - border-radius: 10px; -} - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 40px; - left: 15%; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #fff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); -} - -.carousel-caption .btn { - text-shadow: none; -} - -@media screen and (min-width: 768px) { - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - margin-left: -15px; - font-size: 30px; - } - - .carousel-caption { - right: 20%; - left: 20%; - padding-bottom: 30px; - } -} - -/* ==== Carousel Custom - Start ==== */ - -.carousel { - margin-bottom: 0; -} - -.carousel.full_screen { - height: 1500px; -} - -.qode_slider_preloader{ - width: 100%; - background-color: #1c1c1c; - position: absolute; - z-index: 20; -} - -.qode_slider_preloader{ - height: 1500px; -} - -.qode_slider_preloader .ajax_loader{ - position: absolute; -} - -.carousel-inner .slider_content_outer{ - position: relative; - height: 100%; - width: 1100px; - margin: 0px auto; - z-index: 12; -} - -.carousel-inner .slider_content { - position: absolute; - width: 100%; -} - -.carousel-inner .slider_content .slide_anchor_holder { - margin-top: 8%; -} - -.carousel-inner .item.dark .slider_content .text .slide_anchor_holder .slide_anchor_button { - color: #000; -} - -.carousel-inner .slider_content .slide_anchor_holder .slide_anchor_button { - font-size: 51px; - color: #fff; -} - -.carousel-inner .slider_content .thumb{ - opacity: 0; - filter: alpha(opacity = 0); - height: 100%; - display: inline-block; - vertical-align: middle; -} - -.carousel-inner .slider_content.left{ - text-align: left; -} - -.carousel-inner .slider_content.right{ - text-align: right; -} - -.carousel-inner .slider_content.left .thumb, -.carousel-inner .slider_content.right .thumb{ - display: inline-block; -} - -.carousel-inner .slider_content.center .thumb{ - text-align: center; -} - -.carousel-inner .slider_content.center { - text-align: center; -} - -/*----- SVG ----- */ -.qode_slide-svg-holder svg{ - opacity: 0; - height: auto; -} - -.item.active .qode_slide-svg-holder svg{ - -webkit-animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); - -moz-animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); - -o-animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); - animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); - opacity: 1; -} - -.carousel-inner .active .slider_content .thumb{ - -webkit-animation: rotate 1s 1 ease-out; - -moz-animation: rotate 1s 1 ease-out; - -o-animation: rotate 1s 1 ease-out; - animation: rotate 1s 1 ease-out; - opacity: 1; - filter: alpha(opacity = 100); -} - -.carousel-inner .active .slider_content .thumb.fade{ - -webkit-animation: fade 1s 1 ease-out; - -moz-animation: fade 1s 1 ease-out; - -o-animation: fade 1s 1 ease-out; - animation: fade 1s 1 ease-out; -} - -.carousel-inner .slider_content .thumb img{ - max-height: 100%; -} - -.carousel-inner .slider_content .text{ - text-align: center; - opacity: 0; - filter: alpha(opacity = 0); - position: relative; - display: inline-block; - width: 100%; - margin: 10px 0px 10px 0px; - - -webkit-transform: translateZ(0px); - -moz-transform: translateZ(0px); - -ms-transform: translateZ(0px); - -o-transform: translateZ(0px); - transform: translateZ(0px); -} - -.carousel-inner .active .slider_content .text { - -webkit-animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); - -moz-animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); - -o-animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); - animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); - opacity: 1; - filter: alpha(opacity = 100); -} - -/* one by one element animation - start */ - -.carousel-inner .slider_content .text.one_by_one{ - -webkit-animation: none; - -moz-animation: none; - -o-animation: none; - animation: none; - opacity: 1; -} - -.carousel-inner .slider_content .text.one_by_one h2, -.carousel-inner .slider_content .text.one_by_one h4, -.carousel-inner .slider_content .text.one_by_one .separator, -.carousel-inner .slider_content .text.one_by_one p, -.carousel-inner .slider_content .text.one_by_one a.qbutton, -.carousel-inner .slider_content .text.one_by_one .slide_anchor_holder{ - opacity: 0; - filter: alpha(opacity = 0); - position: relative; - top: 70px; -} - -.carousel-inner .active .slider_content .text.one_by_one h2, -.carousel-inner .active .slider_content .text.one_by_one h4, -.carousel-inner .active .slider_content .text.one_by_one .separator, -.carousel-inner .active .slider_content .text.one_by_one p, -.carousel-inner .active .slider_content .text.one_by_one a.qbutton, -.carousel-inner .active .slider_content .text.one_by_one .slide_anchor_holder{ - -webkit-animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; - -moz-animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; - -o-animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; - animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; - -webkit-animation-fill-mode: both; - -moz-animation-fill-mode: both; - -ms-animation-fill-mode: both; - -o-animation-fill-mode: both; - animation-fill-mode: both; - /*top: 0px;*/ - opacity: 1; - filter: alpha(opacity = 100); - -} - -/* without separator and subtitle above - start */ -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator h2{ - animation-delay:0.15s; - -webkit-animation-delay:0.15s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator p{ - animation-delay:0.3s; - -webkit-animation-delay:0.3s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator a.qbutton{ - animation-delay:0.45s; - -webkit-animation-delay:0.45s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator .slide_anchor_holder { - animation-delay: 0.6s; - -webkit-animation-delay: 0.6s; -} -/* without separator and subtitle above - end */ - -/* with separator and subtitle above - start */ -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator h2{ - animation-delay:0.15s; - -webkit-animation-delay:0.15s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator .separator{ - animation-delay:0.3s; - -webkit-animation-delay:0.3s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator p{ - animation-delay:0.45s; - -webkit-animation-delay:0.45s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator a.qbutton{ - animation-delay:0.6s; - -webkit-animation-delay:0.6s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator .slide_anchor_holder { - animation-delay: 0.75s; - -webkit-animation-delay: 0.75s; -} -/* with separator and subtitle above - end */ - -/* without separator and subtitle bellow - start */ -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator h4{ - animation-delay:0.15s; - -webkit-animation-delay:0.15s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator p{ - animation-delay:0.3s; - -webkit-animation-delay:0.3s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator a.qbutton{ - animation-delay:0.45s; - -webkit-animation-delay:0.45s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator .slide_anchor_holder { - animation-delay: 0.6s; - -webkit-animation-delay: 0.6s; -} -/* without separator and subtitle bellow - end */ - -/* with separator and subtitle bellow - start */ -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator h4{ - animation-delay:0.15s; - -webkit-animation-delay:0.15s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator .separator{ - animation-delay:0.3s; - -webkit-animation-delay:0.3s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator p{ - animation-delay:0.45s; - -webkit-animation-delay:0.45s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator a.qbutton{ - animation-delay:0.6s; - -webkit-animation-delay:0.6s; -} - -.carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator .slide_anchor_holder { - animation-delay: 0.75s; - -webkit-animation-delay: 0.75s; -} -/* with separator and subtitle bellow - end */ - -/* without separator and no subtitle - start */ -.carousel-inner .active .slider_content .text.one_by_one.no_subtitle.no_separator p{ - animation-delay:0.2s; - -webkit-animation-delay:0.2s; -} - -.carousel-inner .active .slider_content .text.one_by_one.no_subtitle.no_separator a.qbutton{ - animation-delay:0.4s; - -webkit-animation-delay:0.4s; -} - -.carousel-inner .active .slider_content .text.one_by_one.no_subtitle.no_separator .slide_anchor_holder { - animation-delay: 0.6s; - -webkit-animation-delay: 0.6s; -} -/* without separator and no subtitle - end */ - -/* with separator and no subtitle - start */ - -.carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator .separator{ - animation-delay:0.15s; - -webkit-animation-delay:0.15s; -} - -.carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator p{ - animation-delay:0.3s; - -webkit-animation-delay:0.3s; -} - -.carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator a.qbutton{ - animation-delay:0.45s; - -webkit-animation-delay:0.45s; -} - -.carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator .slide_anchor_holder { - animation-delay: 0.6s; - -webkit-animation-delay: 0.6s; -} -/* with separator and no subtitle - end */ - -/* one by one element animation - end */ - -.carousel-inner .slider_content .text .qbutton { - margin: 10px 0px 0px 0px; -} - -.carousel-inner .item.dark .slider_content .text .qbutton { - border-color: #303030; - background-color: #303030; - color: #fff; -} - -.carousel-inner .item.dark .slider_content .text .qbutton:hover { - background-color: transparent; - color: #303030; - -} - -.carousel-inner .item.dark .slider_content .text .qbutton.white{ - background-color: transparent; - color: #303030; -} - -.carousel-inner .item.dark .slider_content .text .qbutton.white:hover{ - background-color: #303030; - color: #fff !important; - border-color: #303030; -} - -.carousel-inner .slider_content .text .qbutton.white{ - margin: 10px 0 0 10px; -} - -.carousel-inner h2 { - margin: 10px 0 20px 0; - font-size: 45px; - line-height: 1.071428571428571em; /* 48px / 45px */ -} - -.carousel-inner h2.with_title_border { - margin: 20px 0 30px 0; -} - -.carousel-inner h2.with_title_border span { - display: inline-block; - padding: 0.3em 1.1em; -} - -.carousel-inner h2, -.carousel-inner .q_slide_subtitle { - font-weight: 600; - color: #fff; - text-align: center; - padding: 0px; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); -} - -.carousel-inner h2.with_background_color span { - padding: 10px; -} - -.carousel-inner .q_slide_subtitle { - font-size: 26px; - letter-spacing: 1px; -} - -.carousel-inner .q_slide_subtitle span { - font-size: 1em; - margin-bottom: 13px; - display: inline-block; -} - -.carousel-inner .q_slide_subtitle.with_background_color span { - padding: 10px; - margin-bottom: 12px; -} - -.carousel-inner p { - color: #fff; - text-align: center; - font-size: 21px; - line-height: 1.363157894736842em; /* 29px / 21px */ - font-weight: 400; - margin: 10px 0px 15px 0px; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); -} - -.carousel-inner .dark h2, -.carousel-inner .dark .q_slide_subtitle, -.carousel-inner .dark p{ - color: #000; -} - -.carousel-inner .left .text, -.carousel-inner .left h2, -.carousel-inner .left .q_slide_subtitle, -.carousel-inner .left p{ - text-align: left; -} - -.carousel-inner .right .text, -.carousel-inner .right h2, -.carousel-inner .right .q_slide_subtitle, -.carousel-inner .right p{ - text-align: right; -} - -.carousel-inner { - left: 0 !important; - position: fixed; - overflow: hidden; - width: 100%; - z-index: 1; - transform: translate(0px, 0px); - -ms-transform: translate(0px, 0px); - -moz-transform: translate(0px, 0px); - -webkit-transform: translate(0px, 0px); - -o-transform: translate(0px, 0px); - -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); - transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -} - -.carousel-inner.relative_position{ - position: relative; -} - -.carousel-inner .item img { - display: inline-block !important; -} - -.touch .carousel-inner .item { - background-position: center 0px !important; -} - -.carousel-inner .item .image{ - position: absolute; - top: 0px; - left: 0px; - background-position: center 0px; - background-repeat: no-repeat; - background-size: cover; - width: 100%; - height: 100%; -} - -/* animate image - start */ -@media only screen and (min-width: 1000px){ - .carousel-inner .item.animate_image.zoom_center .image{ - position: absolute; - top: 0%; - left: 0%; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - width: 100%; - height: 110%; - -webkit-backface-visibility: hidden; /* to prevent glittering on slide change */ - backface-visibility: hidden; - } - - .carousel-inner .item.animate_image.zoom_top_left .image, - .carousel-inner .item.animate_image.zoom_top_right .image, - .carousel-inner .item.animate_image.zoom_bottom_left .image, - .carousel-inner .item.animate_image.zoom_bottom_right .image{ - position: absolute; - top: -12%; - left: -12%; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - width: 125%; - height: 125%; - -webkit-backface-visibility: hidden; /* to prevent glittering on slide change */ - backface-visibility: hidden; - } -} - -@media only screen and (max-width: 1000px){ - .carousel-inner .item.animate_image.zoom_center .image, - .carousel-inner .item.animate_image.zoom_top_left .image, - .carousel-inner .item.animate_image.zoom_top_right .image, - .carousel-inner .item.animate_image.zoom_bottom_left .image, - .carousel-inner .item.animate_image.zoom_bottom_right .image{ - transform: none !important; - -webkit-transform: none !important; - } -} -/* animate image - end */ - -.carousel-inner .item .image img{ - display: none !important; - width: 0px; - height: 0px; -} - -.carousel-inner .item .image_pattern { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-position: 0 0; - background-repeat: repeat; - z-index: 2; -} - -.carousel-control { - top: 0px; - width: 23%; - color: #303030; - font-size: 13px; - height: 100%; - background: none; - text-shadow: none; - position: absolute; - border-radius: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border: none; - z-index: 2 !important; - margin: 0px; - outline: none; - cursor: pointer; - -webkit-transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; - -moz-transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; - -o-transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; - -ms-transform: color 0.6s ease-in-out, opacity 0.3s ease-in-out; - transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; -} - -.carousel-control.right { - right: 0; - left: auto; -} - -.carousel-control:hover{ - color: #303030; - opacity: 1 !important; -} - -.carousel-control.dark, -.carousel-control.dark:hover{ - color: #fff; -} - -.carousel-control .prev_nav, -.carousel-control .next_nav{ - height: 54px; - width: 54px; - border: 2px solid #fff; - line-height: 54px; - font-size: 14px; - position: absolute; - top: 50%; - margin-top: -27px; - text-align: center; - z-index: 10; - -webkit-transition: opacity 0.3s ease 0s; - -moz-transition: opacity 0.3s ease 0s; - -o-transition: opacity 0.3s ease 0s; - transition: opacity 0.3s ease-in-out; - opacity: 0; - -webkit-border-radius: 56px; - -moz-border-radius: 56px; - -ms-border-radius: 56px; - -o-border-radius: 56px; - border-radius: 56px; -} - -@media only screen and (max-width: 1000px){ - .carousel-control .prev_nav, - .carousel-control .next_nav { - margin-top: -27px !important; - } -} - -.carousel-control i{ - font-size:30px; - color: #fff; - line-height: 54px; -} -.carousel-control.dark .prev_nav i, -.carousel-control.dark .next_nav i{ - color: #000; -} - -.carousel-control.light .prev_nav i, -.carousel-control.light .next_nav i{ - color: #fff; -} - -.carousel-control.dark .prev_nav, -.carousel-control.dark .next_nav{ - border-color: #000; -} - -.carousel-control.light .prev_nav, -.carousel-control.light .next_nav{ - border-color: #fff; -} - -.carousel-control .prev_nav{ - left: 23px; -} - -.q_slider:hover .carousel-control .prev_nav{ - opacity: 1; -} - -.carousel-control .next_nav{ - right: 23px; -} - -.q_slider:hover .carousel-control .next_nav{ - opacity: 1; -} -.q_slider:hover .carousel-control .next_nav:hover, -.q_slider:hover .carousel-control .prev_nav:hover{ - opacity: 1; - -} - -.carousel-control .thumb_holder{ - width: 150px; - display: block; - position: absolute; - margin: -20px 0px 0px 0px; - top: 50%; - z-index: 9; -} - -.carousel-control .thumb_holder .thumb_top{ - background-color: #fff; - display: block; - position: relative; -} - -.carousel-control.dark .thumb_holder .thumb_top{ - background-color: #000; -} - -.carousel-control.left .thumb_holder .thumb_top{ - -webkit-border-radius:0px 3px 0px 0px; - -moz-border-radius:0px 3px 0px 0px; - -ms-border-radius: 0px 3px 0px 0px; - border-radius:0px 3px 0px 0px; -} - -.carousel-control.right .thumb_holder .thumb_top{ - -webkit-border-radius:3px 0px 0px 0px; - -moz-border-radius:3px 0px 0px 0px; - -ms-border-radius: 3px 0px 0px 0px; - border-radius:3px 0px 0px 0px; -} - -.carousel-control.left .thumb_holder{ - left: -100%; - -webkit-transition: left 0.2s ease-in-out; - -moz-transition: left 0.2s ease-in-out; - -o-transition: left 0.2s ease-in-out; - -ms-transform: left 0.2s ease-in-out; - transition: left 0.2s ease-in-out; - -webkit-border-radius:0px 3px 3px 0px; - -moz-border-radius:0px 3px 3px 0px; - -ms-border-radius: 0px 3px 3px 0px; - border-radius:0px 3px 3px 0px; - display: none; -} - -.slider_thumbs .carousel-control.left:hover .thumb_holder{ - left: 0px; -} - -.in_progress.slider_thumbs .carousel-control.left .thumb_holder{ - left: -100% !important; -} - -.carousel-control.right .thumb_holder{ - right: -100%; - -webkit-transition: right 0.2s ease-in-out; - -moz-transition: right 0.2s ease-in-out; - -o-transition: right 0.2s ease-in-out; - -ms-transform: right 0.2s ease-in-out; - transition: right 0.2s ease-in-out; - -webkit-border-radius:3px 0px 0px 3px; - -moz-border-radius:3px 0px 0px 3px; - -ms-border-radius: 3px 0px 0px 3px; - border-radius:3px 0px 0px 3px; - display: none; -} - -.slider_thumbs .carousel-control.right:hover .thumb_holder{ - right: 0px; -} - -.in_progress.slider_thumbs .carousel-control.right .thumb_holder{ - right: -100% !important; -} - -.carousel-control.left .arrow_left{ - float: left; - height: 40px; - line-height: 40px; - padding: 0px 0px 0px 15px; -} - -.carousel-control.left .numbers{ - float: right; - height: 40px; - line-height: 40px; - padding: 0px 20px 0px 0px; -} - -.carousel-control.right .arrow_right{ - float: right; - height: 40px; - line-height: 40px; - padding: 0px 15px 0px 0px; -} - -.carousel-control.right .numbers{ - float: left; - height: 40px; - line-height: 40px; - padding: 0px 0px 0px 20px; -} - -.carousel-control .img_outer{ - top: 0px; - clear: both; - width: 150px; - height: 47px; - position: relative; - display: block; - overflow: hidden; - margin: 0px 0px -2px 0px; -} - -.carousel-control .img{ - top: -47px; - width: 150px; - height: 47px; - position: relative; - display: block; - overflow: hidden; -} - -.in_progress .carousel-control:hover .img{ - top: -47px !important; -} - -.carousel-control:hover .img{ - top: 0px; - -webkit-transition: top 0.2s ease-in-out 0.2s; - -moz-transition: top 0.2s ease-in-out 0.2s; - -o-transition: top 0.2s ease-in-out 0.2s; - -ms-transform: top 0.2s ease-in-out 0.2s; - transition: top 0.2s ease-in-out 0.2s; -} - -.carousel-control.right .img{ - float: right; -} - -.carousel-control .img img, -.carousel-control .img .video{ - position: absolute; - top: 0px; - left: 0px; - z-index: 2; -} - -.carousel-control .img .video{ - left: -1px; -} - -.carousel-control .img .old{ - z-index: 1; -} - -@media only screen and (max-width: 1300px){ - .carousel-control { - width: 15%; - } -} - -@media only screen and (max-width: 1000px){ - .carousel-control{ - width: 10%; - } - - .carousel-control .prev_nav{ - left: 0px; - opacity: 1; - } - - .carousel-control.left .thumb_holder{ - display: none; - } - - .carousel-control .next_nav{ - right: 0px; - opacity: 1; - } - - .carousel-control.right .thumb_holder{ - display: none; - } -} - -.touch .carousel-control{ - width: 10%; -} - -.touch .carousel-control.left{ - background-position: 30px center !important; -} - -.touch .carousel-control.left .thumb_holder{ - display: none; -} - -.touch .carousel-control.right{ - background-position: 100% center !important; -} - -.touch .carousel-control.right .thumb_holder{ - display: none; -} - -/* old way responsiveness - start */ - -@media (max-width: 1200px) { - - .carousel:not(.advanced_responsiveness) .carousel-inner h2 { - margin-top: 0; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2 span { - font-size: 0.625em !important; - line-height: 1.4em !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .q_slide_subtitle span { - font-size: 0.8em; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2 { - line-height: inherit !important; - } -} - -@media (max-width: 1024px) { - .carousel:not(.advanced_responsiveness) .carousel-inner{ - position: relative; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton { - font-size: 12px; - line-height: 31px; - height: 31px; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i{ - margin: 0px 0px 0px 20px; - } -} - -@media only screen and (max-height: 850px){ - .full_screen:not(.advanced_responsiveness) .carousel-inner .slider_content{ - height: 35%; - } -} - -@media only screen and (max-width: 800px) { - .carousel:not(.advanced_responsiveness) .carousel .carousel-inner .slider_content_outer { - display: table; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .slider_content .thumb { - height: auto; - } - - .carousel:not(.advanced_responsiveness) .carousel .carousel-inner .slider_content { - display: table-cell; - vertical-align: middle; - position: static; - top: 0 !important; - left: 0 !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { - font-size: .425em!important; - } -} - -@media (max-width: 768px) { - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton { - font-size: 11px; - line-height: 27px; - height: 27px; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i { - margin: 0px 0px 0px 17px; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2.with_title_border span { - padding: .3em 0.8em; - } - - .carousel:not(.advanced_responsiveness) .carousel-control.left { - left: 0; - } - .carousel:not(.advanced_responsiveness) .carousel-control.right { - right: 0; - } -} - -@media only screen and (max-height: 600px){ - .full_screen:not(.advanced_responsiveness) .carousel-inner .slider_content{ - height: 25%; - } -} - -@media (max-width: 567px) { - - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton{ - font-size: 10px; - line-height: 23px; - height: 23px; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i{ - margin: 0px 0px 0px 14px; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner p { - line-height: 1.4em !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-control { - display: none; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { - font-size: .38em !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2 span { - font-size: .525em !important; - } -} - -@media (max-width: 480px) { - .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { - font-size: .3em !important; - } -} - -@media (max-width: 320px) { - .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { - font-size: 0.2em !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2 span { - font-size: 0.4em !important; - line-height: 1em !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner p span { - font-size: 60% !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner p { - line-height: 1em !important; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton{ - font-size: 9px; - line-height: 20px; - height: 20px; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i{ - margin: 0px 0px 0px 10px; - } - - .carousel:not(.advanced_responsiveness) .carousel-inner h2.with_title_border { - margin: 0 0 10px; - } -} - -/* old way responsiveness - end */ - -/* advanced responsiveness - start */ -@media (max-width: 1200px) { - .carousel.advanced_responsiveness .carousel-inner h2 { - margin-top: 0; - } -} - -@media (max-width: 1000px) { - .carousel.advanced_responsiveness .carousel-inner{ - position: relative; - } - - .carousel.advanced_responsiveness .carousel-inner > .item { - padding-top: 0px !important; - } - - .carousel.advanced_responsiveness .carousel-control .prev_nav, - .carousel.advanced_responsiveness .carousel-control .next_nav{ - margin-top: 0px !important; - } - - .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content_outer { - display: table; - box-sizing: border-box; - display: table; - padding: 0 5px; - } - - .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content .thumb { - height: auto; - } - - .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content { - display: table-cell; - vertical-align: middle; - position: static; - top: 0 !important; - left: 0 !important; - } - - .carousel.advanced_responsiveness .carousel .carousel-inner .graphic_content{ - text-align: center; - } -} - -@media (max-width: 567px) { - .carousel.advanced_responsiveness .carousel-control { - display: none; - } -} - -@media (max-width: 350px) { - - .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content_outer { - width: 100% !important; - } -} -/* advanced responsiveness - end */ - -.carousel-indicators li{ - background-color: #fff; - opacity: 0.4; - margin: 0px 3px; - -webkit-transition: all 0.6s ease-in-out; - -moz-transition: all 0.6s ease-in-out; - -o-transition: all 0.6s ease-in-out; - -ms-transform: all 0.6s ease-in-out; - transition: all 0.6s ease-in-out; -} - -.carousel-indicators.dark li{ - background-color: #000; -} - -.carousel-indicators .active{ - opacity: 1; - margin: 0px 3px; -} - -@-webkit-keyframes text-from-bottom { - 0% { - -webkit-transform: translate(0, 15%); - opacity: 0; - } - 50% { - -webkit-transform: translate(0, 15%); - opacity: 0; - } - 100% { - -webkit-transform: translate(0, 0); - opacity: 1; - } -} - -@-moz-keyframes text-from-bottom { - 0% { - -moz-transform: translate(0, 15%); - opacity: 0; - } - 50% { - -moz-transform: translate(0, 15%); - opacity: 0; - } - 100% { - -moz-transform: translate(0, 0); - opacity: 1; - } -} - -@-o-keyframes text-from-bottom { - 0% { - -o-transform: translate(0, 15%); - opacity: 0; - } - 50% { - -o-transform: translate(0, 15%); - opacity: 0; - } - 100% { - -o-transform: translate(0, 0); - opacity: 1; - } -} - -@keyframes text-from-bottom { - 0% { - transform: translate(0, 15%); - opacity: 0; - } - 50% { - transform: translate(0, 15%); - opacity: 0; - } - 100% { - transform: translate(0, 0); - opacity: 1; - } -} - -@-webkit-keyframes rotate { - 0% { - -webkit-transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0; - } - 50% { - -webkit-transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0; - } - 100% { - -webkit-transform: perspective(600px) rotateX(0deg) scale(1); - opacity: 1; - } -} - -@-moz-keyframes rotate { - 0% { - -moz-transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0; - } - 50% { - -moz-transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0; - } - 100% { - -moz-transform: perspective(600px) rotateX(0deg) scale(1); - opacity: 1; - } -} - -@-o-keyframes rotate { - 0% { - -o-transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0.2; - } - 50% { - -o-transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0.2; - } - 100% { - -o-transform: perspective(600px) rotateX(0deg) scale(1); - opacity: 1; - } -} - -@keyframes rotate { - 0% { - transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0; - } - 50% { - transform: perspective(600px) rotateX(90deg) scale(.5); - opacity: 0; - } - 100% { - transform: perspective(600px) rotateX(0deg) scale(1); - opacity: 1; - } -} - -@-webkit-keyframes fade { - 0% { - opacity: 0; - } - 50% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -@-moz-keyframes fade { - 0% { - opacity: 0; - } - 50% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -@-o-keyframes fade { - 0% { - opacity: 0; - } - 50% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -@keyframes fade { - 0% { - opacity: 0; - } - 50% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -@-webkit-keyframes text-from-bottom-one-by-one { - 0% { - top: 70px; - opacity: 0; - } - 50% { - top: 45px; - opacity: 0; - } - 100% { - top: 0px; - opacity: 1; - } -} - -@-moz-keyframes text-from-bottom-one-by-one { - 0% { - top: 70px; - opacity: 0; - } - 50% { - top: 45px; - opacity: 0; - } - 100% { - top: 0px; - opacity: 1; - } -} - -@-o-keyframes text-from-bottom-one-by-one { - 0% { - top: 70px; - opacity: 0; - } - 50% { - top: 45px; - opacity: 0; - } - 100% { - top: 0px; - opacity: 1; - } -} - -@keyframes text-from-bottom-one-by-one { - 0% { - top: 70px; - opacity: 0; - } - 50% { - top: 45px; - opacity: 0; - } - 100% { - top: 0px; - opacity: 1; - } -} - -.carousel .video .mobile-video-image { - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - display: none; - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; - z-index: 10; -} - -.carousel .video .video-overlay { - height: 3000px; - left: 0; - opacity: 0; - position: absolute; - top: 0; - width: 100%; - z-index: 11; -} - -.carousel .video .video-overlay.active { - background-image: url("img/pixel-video.png"); - background-position: 0px 0px; - background-repeat: repeat; - opacity: 1; -} - -.carousel .video .video-overlay img{ - display: none !important; -} - -.carousel .video .video-wrap { - top: 0px; - left: 0px; - overflow: hidden; - position: absolute; - width: 100%; - z-index: 10; -} - -.carousel .video .video-wrap .mejs-poster { - background-size: cover !important; - -moz-background-size: cover !important; - -webkit-background-size: cover !important; - -o-background-size: cover !important; -} - -.carousel .video .video-wrap .mejs-container .mejs-controls { - display: none !important; -} - -.carousel .video .video-wrap .mejs-controls .mejs-button button:focus { - outline: none !important; -} - -.carousel .video .video-wrap .mejs-controls .mejs-time-rail .mejs-time-loaded { - background-color: rgba(255, 255, 255, 0.18) !important; -} - -.carousel .video .video-wrap .mejs-container { - background-color: transparent !important; - background-image: none !important; - height: auto !important; -} - -.carousel .video .video-wrap .mejs-mediaelement{ - background: none !important; - border: 0px !important; -} - -.carousel .video .video-wrap .mejs-container .mejs-poster img { - max-width: none !important; - width: 100% !important; -} - -.carousel .video .video-wrap .mejs-controls button { opacity: 0.8; } -.carousel .video .video-wrap .mejs-controls button:hover, .mejs-controls .mejs-fullscreen-button:hover button { opacity: 1!important;} - -.carousel .video .video-wrap .mejs-controls .mejs-time-rail .mejs-time-total { - background: #1f1f1f none repeat scroll 0 0 !important; -} - -.carousel .video .video-wrap .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current { - background: transparent !important; -} - -.carousel .item .text .separator { - margin-top: 40px; - margin-bottom: 40px; - width: 68%; -} -.carousel .item .left .text .separator{ - margin-left: 0; -} -.carousel .item .right .text .separator{ - margin-right: 0; -} - -/*** Custom cursor for slider navigation ***/ -.q_slider .has_custom_cursor .prev_nav, -.q_slider .has_custom_cursor .next_nav, -.no-touch .q_slider .has_custom_cursor .carousel-indicators{ - display:none !important; -} - -/*** Custom cursor for slider navigation end ***/ - - -/* ==== Carousel Custom - End ==== */ - -/* ==== Portfolio Slider, Portfolio Single Slider - Start ==== */ - -.flex-container a:active, .flexslider a:active, .flex-container a:focus, .flexslider a:focus, -.portfolio_slider .flex-container a:active, .portfolio_slider .flexslider a:active, .portfolio_slider .flex-container a:focus, .portfolio_slider .flexslider a:focus, -.qode_carousels .flex-container a:active, .qode_carousels a:active, .qode_carousels .flex-container a:focus, .qode_carousels a:focus{ - outline: 0; -} - -.portfolio_slides, -.slides, -.flex-control-nav, -.flex-direction-nav, -.caroufredsel-direction-nav -{ - margin: 0; - padding: 0; - list-style: none; -} - -.flexslider .slides>li{ - background-color: transparent; - display: none; - position: relative; - margin: 0; -} - -.caroufredsel_wrapper { - cursor: grab!important; - cursor: -moz-grab!important; - cursor: -webkit-grab!important; - margin: 0px!important; -} - -.portfolio_slider .portfolio_slides, -.qode_carousels .slides{ - opacity: 0; -} - -.portfolio_slider .portfolio_slides>li, -.qode_carousels .slides>li{ - background-color: transparent; - position: relative; - margin: 0; - float: left; -} - -.qode_carousels .slides>li{ - margin: 0 2px 0 0; -} - -.flexslider .slides img, -.portfolio_slider .portfolio_slides img, -.qode_carousels .slides img{ - width: 100%; - display: block; -} - -.gallery_frame{ - width: 100%; - height:100%; - position: absolute; - top: 0; - text-align: center; - -} -.wpb_flexslider.flexslider.have_frame{ - width: 645px; - margin: 0 auto; - overflow: visible; -} - -.frame_holder > .wpb_wrapper { - padding: 34px 0 102px 0; - position: relative; -} -.frame_holder.frame_holder2 > .wpb_wrapper{ - padding: 48px 0 75px 0; -} -.slides:after, -.portfolio_slides:after{ - content: "."; - display: block; - clear: both; - visibility: hidden; - line-height: 0; - height: 0; -} - -html[xmlns] .slides, -html[xmlns] .portfolio_slides{ - display: block; -} - -* html .slides, -* html .portfolio_slides{ - height: 1%; -} - -.no-js .slides>li:first-child, -.no-js .portfolio_slides>li:first-child{ - display: block; -} - -.flexslider, -.portfolio_slider { - margin: 0 0 60px; - position: relative; - zoom: 1; - -} -.wpb_flexslider.flexslider{ - overflow:hidden; -} -.portfolio_slider { - margin: 0; - width: 100.2%; -} - -.boxed .portfolio_slider{ - margin: 0 -25px 60px; - overflow: hidden; -} - -.flex-viewport, -.portfolio_slider .flex-viewport{ - max-height: 2000px; - -webkit-transition: all 1s ease; - -moz-transition: all 1s ease; - transition: all 1s ease; -} - -.loading .flex-viewport{ - max-height: 300px; -} - -.flexslider .slides, -.portfolio_slider .portfolio_slides, -.qode_carousels .slides{ - zoom: 1; -} -.flexslider ul{ - padding:0; -} -.portfolio_slider .flex-direction-nav, -.flexslider .flex-direction-nav{ - *height: 0; -} - -.flex-direction-nav a, -.caroufredsel-direction-nav a -{ - width: 42px; - height: 42px; - line-height: 42px; - margin: -23px 0 0; - display: block; - position: absolute; - top: 50%; - z-index: 10; - cursor: pointer; - text-align: center; - -webkit-transition: all .3s ease 0s; - -moz-transition: all .3s ease 0s; - -o-transition: all .3s ease 0s; - color: #8a8a8a; - background-color:transparent; - text-align:center; - z-index: 200; - border:2px solid #fff; -} - -.flex-direction-nav a { - -webkit-box-sizing: initial; - -moz-box-sizing: initial; - box-sizing: initial; -} - -.flexslider:hover .flex-direction-nav a.flex-prev:hover, -.flexslider:hover .flex-direction-nav a.flex-next:hover, -.portfolio_slider:hover .flex-direction-nav a.flex-prev:hover, -.portfolio_slider:hover .flex-direction-nav a.flex-next:hover, -.portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover, -.portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover, -.blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover, -.blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover -{ - - - background-color: #fff; -} -.flexslider:hover .flex-direction-nav a.flex-prev:hover i, -.flexslider:hover .flex-direction-nav a.flex-next:hover i, -.portfolio_slider:hover .flex-direction-nav a.flex-prev:hover i, -.portfolio_slider:hover .flex-direction-nav a.flex-next:hover i, -.portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover i, -.portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover i, -.blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover i, -.blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover i -{ - - color:#8a8a8a; -} -.flex-direction-nav a i, -.caroufredsel-direction-nav a i -{ - line-height: 42px; - color: #fff; - font-size: 22px; -} -.have_frame .flex-direction-nav a i{ - display: none; -} -.flexslider .flex-next, -.portfolio_slider .flex-next, -.portfolio_slider .caroufredsel-next -{ - right: 15px; - -webkit-border-radius:2em; - -moz-border-radius:2em; - -ms-border-radius: 2em; - border-radius:2em; -} -.have_frame.flexslider .flex-next{ - right: -80px; - -webkit-border-radius:0; - -moz-border-radius:0; - -ms-border-radius: 0; - border-radius:0; - background-image: url('img/frame_arrow_right.png'); - background-repeat: no-repeat; - background-position: center center; - width: 25px; - height: 67px; - border: none; -} -.have_frame.flexslider .flex-next:hover{ - background-color: transparent !important; - background-image: url('img/frame_arrow_right_hover.png'); -} -.flexslider .flex-prev, -.portfolio_slider .flex-prev, -.portfolio_slider .caroufredsel-prev -{ - left: 15px; - -webkit-border-radius:2em; - -moz-border-radius:2em; - -ms-border-radius: 2em; - border-radius:2em; -} -.have_frame.flexslider .flex-prev{ - left: -80px; - -webkit-border-radius:0; - -moz-border-radius:0; - -ms-border-radius: 0; - border-radius:0; - background-image: url('img/frame_arrow_left.png'); - background-repeat: no-repeat; - background-position: center center; - width: 25px; - height: 67px; - border: none; -} -.have_frame.flexslider .flex-prev:hover{ - background-color: transparent !important;; - background-image: url('img/frame_arrow_left_hover.png'); -} -@media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { - .have_frame.flexslider .flex-prev{ - background-image: url('img/frame_arrow_left@1_5x.png'); - -o-background-size: 25px 67px; - -webkit-background-size: 25px 67px; - -moz-background-size: 25px 67px; - background-size: 25px 67px; - } - .have_frame.flexslider .flex-prev:hover{ - background-image: url('img/frame_arrow_left_hover@1_5x.png'); - } - .have_frame.flexslider .flex-next{ - background-image: url('img/frame_arrow_right@1_5x.png'); - -o-background-size: 25px 67px; - -webkit-background-size: 25px 67px; - -moz-background-size: 25px 67px; - background-size: 25px 67px; - } - .have_frame.flexslider .flex-next:hover{ - background-image: url('img/frame_arrow_right_hover@1_5x.png'); - } -} - -@media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { - .have_frame.flexslider .flex-prev{ - background-image: url('img/frame_arrow_left@2x.png'); - -o-background-size: 25px 67px; - -webkit-background-size: 25px 67px; - -moz-background-size: 25px 67px; - background-size: 25px 67px; - } - .have_frame.flexslider .flex-prev:hover{ - background-image: url('img/frame_arrow_left_hover@2x.png'); - } - .have_frame.flexslider .flex-next{ - background-image: url('img/frame_arrow_right@2x.png'); - -o-background-size: 25px 67px; - -webkit-background-size: 25px 67px; - -moz-background-size: 25px 67px; - background-size: 25px 67px; - } - .have_frame.flexslider .flex-next:hover{ - background-image: url('img/frame_arrow_right_hover@2x.png'); - } -} - -.flex-direction-nav .flex-disabled{ - cursor: default; -} - -/* ==== Portfolio Slider, Portfolio Single Slider - End ==== */ - -/* ==== Qode Carousel Slider - Start ==== */ - -.qode_carousels .slides>li .first_image_holder, -.qode_carousels .slides>li .second_image_holder{ - display: block; - position: relative; - width: 100%; - opacity: 1; - -webkit-transition: opacity 0.4s ease-in-out; - -ms-transition: opacity 0.4s ease-in-out; - -moz-transition: opacity 0.4s ease-in-out; - -o-transition: opacity 0.4s ease-in-out; - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; -} - -.qode_carousels .slides>li .second_image_holder{ - position: absolute; - top: 0; - left: 0; -} - -.qode_carousels .slides>li .second_image_holder, -.qode_carousels .slides > li .carousel_item_holder:hover .first_image_holder.has_hover_image{ - opacity: 0; -} - -.qode_carousels .slides > li .carousel_item_holder:hover .second_image_holder.has_hover_image{ - opacity: 1; -} - -.qode_carousels{ - padding: 0; - position: relative; - display: block; - zoom: 1; -} - -.qode_carousels_holder.two_rows .slides > li .carousel_item_holder { - margin-bottom: 15px; - position: relative; -} - -.qode_carousels .flex-direction-nav { - height: 0; - display: none !important; -} - -/* Control Nav */ -.qode_carousels .flex-control-nav{ - width: 100%; - text-align: center; - position: absolute; - bottom: -60px; -} - -.qode_carousels .flex-control-nav li{ - margin: 0 3px; - display: inline-block; - zoom: 1; - display: inline; -} - -.qode_carousels .flex-control-paging li a{ - width: 9px; - height: 9px; - display: inline-block; - border: 1px solid #eaeaea; - background-color: #fff; - cursor: pointer; - text-indent: -9999px; - -webkit-border-radius: 20px; - -moz-border-radius: 20px; - -o-border-radius: 20px; - border-radius: 20px; -} - -.qode_carousels .flex-control-paging li a.flex-active{ - background-color: #1abc9c; - cursor: default; - border: none; -} - -.qode_carousels.gray .flex-control-paging li a.flex-active { - cursor: default; -} - -/* ==== Qode Carousel Slider - End ==== */ - -.wpb_row, .wpb_content_element, -ul.wpb_thumbnails-fluid > li, -.last_toggle_el_margin, .wpb_button { - margin-bottom: 0 !important; -} - -/* ========================================================================== - Clients styles - ========================================================================== */ -.qode_clients .qode_client_holder { - float: left; - text-align: center; - margin-bottom: 35px; -} - -.qode_clients.two_columns .qode_client_holder { - width: 50%; -} - -.qode_clients.three_columns .qode_client_holder { - width: 33.33%; -} - -.qode_clients.four_columns .qode_client_holder { - width: 25%; -} - -.qode_clients.five_columns .qode_client_holder { - width: 20%; -} - -.qode_clients.six_columns .qode_client_holder { - width: 16.66666666666667%; -} - -.qode_clients .qode_client_holder_inner { - position: relative; - margin: 0 20px; -} - -.qode_clients .qode_client_holder_inner:before, -.qode_clients .qode_client_holder_inner:after { - display: block; - content: ""; - position: absolute; -} - -.qode_clients .qode_client_holder_inner:before { - height: 100%; - right: -20px; - width: 1px; - border-right: 1px solid #eaeaea; -} - -.qode_clients .qode_client_holder_inner:after { - width: 100%; - bottom: -20px; - height: 1px; - border-bottom: 1px solid #eaeaea; -} - -.qode_clients .qode_client_holder.border-bottom-none .qode_client_holder_inner:after { - border-bottom: 0; -} - -.qode_clients.two_columns .qode_client_holder:nth-child(2n) .qode_client_holder_inner:before, -.qode_clients.three_columns .qode_client_holder:nth-child(3n) .qode_client_holder_inner:before, -.qode_clients.four_columns .qode_client_holder:nth-child(4n) .qode_client_holder_inner:before, -.qode_clients.five_columns .qode_client_holder:nth-child(5n) .qode_client_holder_inner:before, -.qode_clients.six_columns .qode_client_holder:nth-child(6n) .qode_client_holder_inner:before { - border-right-width: 0; -} - -.qode_clients .qode_client_holder a { - display: inline-block; - vertical-align: middle; - max-width: 100%; - line-height: 0; - -webkit-transition: opacity 0.6s ease-out; - -moz-transition: opacity 0.6s ease-out; - -o-transition: opacity 0.6s ease-out; - -ms-transform: opacity 0.6s ease-out; - transition: opacity 0.6s ease-out; -} - -.qode_clients .qode_client_holder a:hover { - opacity: 0.4; -} - -/* ========================================================================== - Animated icon with text styles - ========================================================================== */ -.animated_icons_with_text .animated_icon_with_text_holder { - float: left; - text-align: center; -} - -.animated_icons_with_text.two_columns .animated_icon_with_text_holder { - width: 50%; -} - -.animated_icons_with_text.three_columns .animated_icon_with_text_holder { - width: 33.33%; -} - -.animated_icons_with_text.four_columns .animated_icon_with_text_holder { - width: 25%; -} - -.animated_icons_with_text.five_columns .animated_icon_with_text_holder { - width: 20%; -} - -.animated_icons_with_text.six_columns .animated_icon_with_text_holder { - width: 16.66666666666667%; - -} - -.animated_icons_with_text .animated_icon_with_text_inner { - position: relative; - padding: 0px 20px; - height: 85px; - -} - -.animated_icons_with_text .animated_icon_with_text_inner:before, -.animated_icons_with_text .animated_icon_with_text_inner:after { - display: block; - content: ""; - position: absolute; -} - -.animated_icons_with_text .animated_icon_with_text_inner:before { - height: 100%; - right: 0px; - width: 1px; - border-right: 1px solid #f5f5f5; -} - -.animated_icons_with_text .animated_icon_with_text_inner:after { - width: 100%; - bottom: 0px; - height: 1px; - border-bottom: 1px solid #f5f5f5; -} - -.animated_icons_with_text .animated_icon_with_text_holder.border-bottom-none .animated_icon_with_text_inner:after { - border-bottom: none; -} - -.animated_icons_with_text.two_columns .animated_icon_with_text_holder:nth-child(2n) .animated_icon_with_text_inner:before, -.animated_icons_with_text.three_columns .animated_icon_with_text_holder:nth-child(3n) .animated_icon_with_text_inner:before, -.animated_icons_with_text.four_columns .animated_icon_with_text_holder:nth-child(4n) .animated_icon_with_text_inner:before, -.animated_icons_with_text.five_columns .animated_icon_with_text_holder:nth-child(5n) .animated_icon_with_text_inner:before, -.animated_icons_with_text.six_columns .animated_icon_with_text_holder:nth-child(6n) .animated_icon_with_text_inner:before { - border-right-width: 0; -} - -.animated_icon_holder{ - height: 100%; - padding:0 0 0 15px; - display: block; - width: 81px; - float: left; - position: relative; -} - -.animated_icon{ - height: 100%; - width: 100%; - position: relative; -} - -.animated_icon_inner span{ - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - backface-visibility: hidden; - backface-visibility: hidden; - left: 0px; - position: absolute; - top: 0; - -webkit-transition: 200ms ease-in; - -moz-transition: 200ms ease-in; - -o-transition: 200ms ease-in; - transition: 200ms ease-in; -} - -.animated_icon_inner span.animated_icon_back{ - -webkit-transform: rotateY(-180deg); - -moz-transform: rotateY(-180deg); - -ms-transform: rotateY(-180deg); - -o-transform: rotateY(-180deg); - transform: rotateY(-180deg); -} - -.animated_icon_with_text_holder:hover .animated_icon_inner span.animated_icon_back{ - -webkit-transform: rotateY(0); - -moz-transform: rotateY(0); - -ms-transform: rotateY(0); - -o-transform: rotateY(0); - transform: rotateY(0); -} - -.animated_icon_with_text_holder:hover .animated_icon_inner span { - -webkit-transform: rotateY(180deg); - -moz-transform: rotateY(180deg); - -ms-transform: rotateY(180deg); - -o-transform: rotateY(180deg); - transform: rotateY(180deg); -} - -.animated_icon_inner{ - height: 81px; - width: 100%; - position: absolute; - left:0px; - top: 50%; - margin: -41px 0 0 0; -} - -.animated_icon_inner i { - width: 77px; - height: 77px; - line-height: 77px; - background: transparent; - -o-border-radius: 100px; - -moz-border-radius: 100px; - -webkit-border-radius: 100px; - border-radius: 100px; - margin: 0; - border: 2px solid #c0c0c0; - color: #c0c0c0; - font-size:35px; -} - -.animated_icon_inner span.animated_icon_back i{ - background-color: #1abc9c; - color:#fff; - border-color: #1abc9c; -} - -.animated_icon_with_text_holder .animated_text_holder { - text-align: left; - width: 100%; - height: 100%; -} - -.animated_icon_with_text_holder .animated_text_holder_wrap{ - display: block; - padding: 0 0 0 116px; - height: 100%; -} - -.animated_icon_with_text_holder .animated_text_holder_wrap_inner{ - width: 100%; - height: 100%; - position: relative; -} - -.animated_text_holder_inner{ - position: absolute; - left: 0; - width: 100%; - top: 0; - overflow: hidden; - height: 100%; -} - -.animated_icon_with_text_holder .animated_title, -.animated_icon_with_text_holder .animated_text{ - display: table; - position: absolute; - overflow: hidden; - width: 100%; - height: 100%; -} - -.animated_icon_with_text_holder .animated_title_inner, -.animated_icon_with_text_holder .animated_text p{ - display: table-cell; - vertical-align: middle; -} - -.animated_icon_with_text_holder .animated_title, -.animated_icon_with_text_holder .animated_title_inner, -.animated_icon_with_text_holder .animated_text, -.animated_icon_with_text_holder .animated_text p{ - -webkit-transition: 200ms ease-in; - -moz-transition: 200ms ease-in; - -o-transition: 200ms ease-in; - transition: 200ms ease-in; -} - -.animated_icon_with_text_holder .animated_text { - -webkit-transform: translateY(-100%); - -moz-transform: translateY(-100%); - -ms-transform: translateY(-100%); - -o-transform: translateY(-100%); - transform: translateY(-100%); - -webkit-transform: translate3d(0, -100%, 0); - -moz-transform: translate3d(0, -100%, 0); - -ms-transform: translate3d(0, -100%, 0); - -o-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); -} - -.animated_icon_with_text_holder .animated_text p{ - -webkit-transform: translateY(100%); - -moz-transform: translateY(100%); - -ms-transform: translateY(100%); - -o-transform: translateY(100%); - transform: translateY(100%); - -webkit-transform: translate3d(0, 100%, 0); - -moz-transform: translate3d(0, 100%, 0); - -ms-transform: translate3d(0, 100%, 0); - -o-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); -} - -.animated_icon_with_text_holder:hover .animated_text, -.animated_icon_with_text_holder:hover .animated_text p{ - -webkit-transform: translateY(0); - -moz-transform: translateY(0); - -ms-transform: translateY(0); - -o-transform: translateY(0); - transform: translateY(0); - -webkit-transform: translate3d(0, 0, 0); - -moz-transform: translate3d(0, 0, 0); - -ms-transform: translate3d(0, 0, 0); - -o-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - -webkit-transition: 350ms ease-out; - -moz-transition: 350ms ease-out; - -o-transition: 350ms ease-out; - transition: 350ms ease-out; -} - -.animated_icon_with_text_holder:hover .animated_title_inner{ - -webkit-transform: translateY(-100%); - -moz-transform: translateY(-100%); - -ms-transform: translateY(-100%); - -o-transform: translateY(-100%); - transform: translateY(-100%); - -webkit-transform: translate3d(0, -100%, 0); - -moz-transform: translate3d(0, -100%, 0); - -ms-transform: translate3d(0, -100%, 0); - -o-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - -webkit-transition: 350ms ease-out; - -moz-transition: 350ms ease-out; - -o-transition: 350ms ease-out; - transition: 350ms ease-out; -} - -.animated_icon_with_text_holder:hover .animated_title{ - -webkit-transform: translateY(100%); - -moz-transform: translateY(100%); - -ms-transform: translateY(100%); - -o-transform: translateY(100%); - transform: translateY(100%); - -webkit-transform: translate3d(0, 100%, 0); - -moz-transform: translate3d(0, 100%, 0); - -ms-transform: translate3d(0, 100%, 0); - -o-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - -webkit-transition: 350ms ease-out; - -moz-transition: 350ms ease-out; - -o-transition: 350ms ease-out; - transition: 350ms ease-out; -} - -/* ========================================================================== - Service table shorcode start styles - ========================================================================== */ - -.service_table_holder{ - display: block; - position: relative; - border-color: #f6f6f6; - border-width: 1px; - border-style: none; -} - -.service_table_inner{ - display: block; - position: relative; - list-style: none; - margin: 0; - padding: 0; -} - -.service_table_inner ul{ - padding: 0 !important; -} - -.service_table_inner li{ - display: block; - margin: 0; - padding: 0; - list-style: none; - text-align: center; - border-bottom: 1px solid #f6f6f6; -} - -.service_table_inner > li{ - background-color: #fff; -} - -.service_table_inner li li{ - padding: 9px 20px; -} - -.service_table_inner li:last-child{ - border-bottom: 0; -} - -.service_table_inner li.service_table_title_holder{ - display: block; - position: relative; - padding: 31px 20px 20px; - background-color: #fff; - border: none; -} -.service_table_inner li.service_table_title_holder i{ - color: #1abc9c; - -} -.service_table_title_inner{ - position: relative; - display: table; - width: 100%; - height: 100%; - text-align: center; -} - -.service_table_title_inner2{ - display: table-cell; - width: 100%; - height: 100%; - padding: 20px 20px 25px; - vertical-align: middle; -} - -.service_table_inner li.service_table_title_holder.background_image_type{ - background-color: transparent !important; - border: 0 !important; - padding: 0; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; -} - -.service_table_inner li.service_table_title_holder.background_color_type .service_table_title_inner2{ - padding: 0; -} - -.service_table_title_holder .service_title{ - display: block; -} - -.service_table_title_holder i{ - display: block; - line-height: 1em; - padding: 33px 0 0; -} - -/* ========================================================================== - Service table shorcode end styles - ========================================================================== */ -/* ========================================================================== - End Clients styles - ========================================================================== */ -.header_top_bottom_holder{ - position: relative; -} - -.qode_search_form{ - background: none repeat scroll 0 0 #262626; - color: #fff; - margin: 0; - overflow: hidden; - width: 100%; - height: 0px; - position: absolute; - top:0; - left:0; -} - -.qode_search_form .qode_icon_in_search { - color: #959595; - font-size: 13px; - display: inline-block; - padding: 0px 0px 0px 45px; - float: left; - line-height: 50px; -} - -.qode_search_form input, -.qode_search_form input:focus{ - background-color: #262626; - border: medium none; - box-shadow: none; - color: #959595; - display: inline-block; - font-size: 13px; - line-height: 20px; - height: 20px; - margin: 15px 0px; - width: 90%; - padding: 0px 45px 0px 10px; - font-family: inherit; - outline: none; - outline-offset:0px; - -webkit-appearance: none; - border-radius: 0; - float: left; -} - -.qode_search_form input:focus{ - outline-offset: 0px !important; -} - -::-webkit-input-placeholder, -:-moz-placeholder, -::-moz-placeholder, -:-ms-input-placeholder{ - color: #959595; - margin: 10px 0px 0px 0px; -} - -@media only screen and (max-width: 1200px){ - .qode_search_form input{ - width: 80%; - } -} - -@media only screen and (max-width: 768px){ - .qode_search_form input{ - width: 70%; - } -} - -@media only screen and (max-width: 500px){ - .qode_search_form input{ - width: 65%; - } -} - -.qode_search_form .container_inner{ - position: relative; -} - -.qode_search_form .container .qode_icon_in_search { - padding: 0px; -} - -.qode_search_form .container input{ - width: 90%; - padding: 0px 0px 0px 10px; -} - -.qode_search_form input[type="submit"] { - border: 0 none; - clip: rect(0px, 0px, 0px, 0px); - height: 1px; - margin: -1px; - padding: 0; - position: absolute; - width: 1px; - visibility: hidden; -} - -.qode_search_form .qode_search_close{ - color: #959595; - font-size: 13px; - position: absolute; - line-height: 50px; - height: 50px; - top: 0px; - right: 45px; -} - -.qode_search_form .container .qode_search_close{ - right: 0px; -} - -/* slide from header bottom */ - -.qode_search_form_2{ - background: none repeat scroll 0 0 #f1f1f1; - color: #fff; - margin: 0; - overflow: hidden; - width: 100%; - height: 100px; - bottom: 0; - position: absolute; - transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53); - -webkit-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53); - -moz-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53); - left:0; - opacity: 1; -} - -.qode_search_form_2.animated{ - transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53), opacity 0s ease 0s; - -webkit-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53), opacity 0s ease 0s; - -moz-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53), opacity 0s ease 0s; - left:0; - opacity: 1; -} - -.qode_search_form_2 .container{ - z-index:auto; -} - -.qode_search_form_2 .form_holder_outer { - display: table; - height: 100px; - width: 100%; -} -.qode_search_form_2 .form_holder { - display: table-cell; - vertical-align: middle; - position:relative; -} -.qode_search_form_2.animated .form_holder_outer { - height: 100px; -} - -.qode_search_form_2 .container_inner .form_holder { - padding: 0px; -} - -.qode_search_form_2 .form_holder { - padding: 0 45px; -} - -.qode_search_form_2 input, -.qode_search_form_2 input:focus{ - background-color: transparent; - border: medium none; - box-shadow: none; - color: #9d9d9d; - font-size: 15px; - font-weight: 600; - display: inline-block; - vertical-align: middle; - width: 90%; - padding: 0; - font-family: inherit; - outline: none; - outline-offset:0px; - -webkit-appearance: none; - border-radius: 0; - text-transform: uppercase; -} - -.qode_search_form_2 input:focus{ - outline-offset: 0px !important; -} - -.qode_search_form_2 .qode_search_submit { - width: auto; - cursor: pointer; - font-size:50px; - position:absolute; - right: 45px; - top: 50%; - -moz-transform: translateY(-50%); - -webkit-transform: translateY(-50%); - transform: translateY(-50%); - transition: color 0.4s ease; - -webkit-transition: color 0.4s ease; - -moz-transition: color 0.4s ease; - color: #696969; - padding: 0 0 0 1px; -} -.qode_search_form_2 .container_inner .qode_search_submit { - right:0; -} - -.qode_search_form_2 .qode_search_submit:hover{ - color:#1abc9c -} - -.qode_search_form_2.disabled .qode_search_submit, -.qode_search_form_2.disabled .qode_search_submit:hover { - cursor:default; - color:#959595; -} - - -/* search covers header */ -.qode_search_form_3{ - display: none; - color: #fff; - position: absolute; - top: 0; - left: 0; - width: 100%; - z-index: 115; - background:#fff; -} -.admin-bar .qode_search_form_3 { - padding-top: 33px; -} - - -.qode_search_form_3 .form_holder_outer{ - display: table; - width: 100%; - height:100%; -} - -.qode_search_form_3 .form_holder{ - display: table-cell; - vertical-align: middle; - padding:0px 45px; - position:relative; -} - -.qode_search_form_3 .container_inner .form_holder{ - padding: 0px; -} - -.qode_search_form_3 input, -.qode_search_form_3 input:focus{ - background-color: transparent; - border: medium none; - box-shadow: none; - color: #9d9d9d; - font-size: 15px; - font-weight: 600; - display: inline-block; - width: 90%; - padding:0; - font-family: inherit; - outline: none; - outline-offset:0px; - -webkit-appearance: none; - border-radius: 0; - float: left; - text-transform: uppercase; - margin: 0; -} - -.qode_search_form_3 input:focus{ - outline-offset: 0px !important; -} - -.qode_search_form_3 input[type="submit"]{ - border: 0 none; - clip: rect(0px,0px,0px,0px); - height: 1px; - margin: -1px; - padding: 0; - position: absolute; - width: 1px; - visibility: hidden; -} - -.qode_search_form_3 .qode_search_close{ - font-size: 34px; - position: absolute; - right: 45px; - top:50%; - -webkit-transform: translateY(-50%); - -moz-transform: translateY(-50%); - -ms-transform: translateY(-50%); - -o-transform: translateY(-50%); - transform: translateY(-50%); - line-height:1em; -} - -.qode_search_form_3 .container_inner .qode_search_close{ - right: 0; -} - -.qode_search_form_3 .qode_search_close a{ - color: #9d9d9d; - display: inline-block; -} -.qode_search_form_3 .qode_search_close a:hover{ - color: #1abc9c; -} - -::-webkit-input-placeholder, -:-moz-placeholder, -::-moz-placeholder, -:-ms-input-placeholder{ - color: #959595; - margin: 10px 0px 0px 0px; -} - -.qode_search_form_3 .qode_search_close a i{ - vertical-align: top; -} - -/* insert end */ - -/*----------------------FULLSCREEN SEARCH style start--------------------------*/ - -.side_menu_button{ - position:relative; -} - -.fullscreen_search_holder{ - position:fixed; - top:0; - left:0; - width:100%; - height:100%; - z-index:105; - opacity:0; -} - -.fullscreen_search_table{ - display: table; - width:100%; - height:100%; -} - -.fullscreen_search_cell{ - display: table-cell; - vertical-align: middle; - width:100%; - height:100%; - text-align:center; -} - -.fullscreen_search_holder .search_label{ - font-size:30px; - line-height:1em; - color: #a1a1a1; - vertical-align:bottom; - font-family:inherit; - margin-right:5px; -} - -.fullscreen_search_holder .field_holder{ - width:30%; - display:inline-block; - vertical-align:bottom; - position:relative; - border-bottom:1px solid #a1a1a1; -} - -.fullscreen_search_holder .field_holder .line{ - position:absolute; - bottom:-1px; - left:0; - height:1px; - width:0; - background-color: #1abc9c; - -webkit-transition: width 0.4s ease; - transition: width 0.4s ease; -} - -.fullscreen_search_holder .search_field{ - width:100%; - border-left:none; - border-top:none; - border-right:none; - border-bottom:none; - background:transparent; - outline:none; - height:100%; - font-size:25px; - color: #9d9d9d; - line-height:1em; - position:relative; - font-family: inherit; -} - -.fullscreen_search_holder .search_submit{ - border:none; - background:transparent; - outline:none; - width: auto; - cursor: pointer; - font-family: 'FontAwesome'; - font-size:20px; - line-height:1em; - -webkit-transition: color 0.2s ease; - transition: color 0.2s ease; - color: #a1a1a1; -} - -.fullscreen_search_holder .search_submit:hover{ - color: #1abc9c; -} - -.fullscreen_search_holder .search_close_holder{ - float:right; - -} - -.fullscreen_search_holder .close_container{ - position:absolute; - left:0; - top:0; - width:100%; -} - -.fullscreen_search_holder .close_container a{ - opacity:0; - visibility:hidden; - -webkit-transition: opacity 0.2s ease, color 0.2s ease; - transition: opacity 0.2s ease, color 0.2s ease; -} - -.fullscreen_search_holder .close_container a:hover{ - color: #1abc9c; -} - -.fullscreen_search_holder .close_container .search_close_holder{ - margin-right: 45px; -} - -.fullscreen_search_holder .close_container .container_inner .search_close_holder{ - margin-right: 0px; -} - - -/*---Fulscreen search FROM CIRCLE style---*/ - -.fullscreen_search_overlay{ - position:absolute; - width:2000px; - height:2000px; - margin-top:-1000px; - margin-left:-1000px; - top:50%; - left:0; - border-radius:100%; - opacity:0; - z-index:99; - -ms-transform-origin: 50%; - -webkit-transform-origin: 50%; - transform-origin: 50%; - -ms-transform: scale(0); - -webkit-transform: scale(0); - -moz-transform: scale(0); - -o-transform: scale(0); - transform: scale(0); - background-color: rgba(255,255,255,0.98); - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -ms-transition: -ms-transform 0.6s cubic-bezier(0.4,0,0.2,1), opacity 0.6s cubic-bezier(0.4,0,0.2,1); - -webkit-transition: -webkit-transform 0.6s cubic-bezier(0.4,0,0.2,1), opacity 0.6s cubic-bezier(0.4,0,0.2,1); - transition: transform 0.6s cubic-bezier(0.4,0,0.2,1), opacity 0.6s cubic-bezier(0.4,0,0.2,1); -} - - -.fullscreen_search_overlay.animate{ - -ms-transform: scale(3); - -moz-transform: scale(3); - -o-transform: scale(3); - -webkit-transform: scale(3); - transform: scale(3); - opacity:1; -} - -.fullscreen_search_holder.from_circle{ - -webkit-transition: opacity 0.3s ease; - transition: opacity 0.3s ease; - display:none; - opacity:0; - visibility:visible; - z-index:111; -} - - -/*---Fulscreen search FADE style---*/ - -.fullscreen_search_holder.fade{ - visibility: hidden; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - opacity: 0; - background-color:rgba(255,255,255,0.98); - z-index:111; -} - -.search_fade_out .fullscreen_search_holder.fade{ - -webkit-animation: search_fade_out .25s linear both; - animation: search_fade_out .25s linear both ; -} - -.search_fade_in .fullscreen_search_holder.fade.animate{ - -webkit-animation: search_fade_in .25s linear both; - animation: search_fade_in .25s linear both; -} - -.fullscreen_search_holder.fade.animate .fullscreen_search_close{ - opacity:1; - visibility:visible; -} - - -@-webkit-keyframes search_fade_out { - 0%{ - opacity:1; - visibility: visible; - } - 100%{ - opacity:0; - visibility: hidden; - } -} -@keyframes search_fade_out{ - 0%{ - opacity:1; - visibility: visible; - } - 100% { - opacity:0; - visibility: hidden; - } -} -@-webkit-keyframes search_fade_in { - 0% { - opacity:0; - visibility: hidden; - } - 100% { - opacity:1; - visibility: visible; - } -} -@keyframes search_fade_in{ - 0%{ - opacity:0; - visibility: hidden; - } - 100%{ - opacity:1; - visibility: visible; - } -} -/*----------------Search styles end---------------------*/ - -/****** Cover Boxes start style *******/ - -.cover_boxes{ - position: relative; - overflow: hidden; -} - -.cover_boxes ul{ - list-style: none; - margin: 0px -20px 0px 0px; - padding: 0px; - width: 200%; -} - -.cover_boxes ul li{ - float: left; - margin-right: 20px; - overflow: hidden; - position: relative; - width: 265px; - -webkit-transition: all 0.5s ease 0s; - -moz-transition: all 0.5s ease 0s; - -o-transition: all 0.5s ease 0s; - transition: all 0.5s ease 0s; -} - -.cover_boxes ul li.act{ - width: 530px; -} - -.cover_boxes ul li .box{ - width: 530px; -} - -.cover_boxes ul li .box .thumb { - display: inline-block; - float: left; - margin-right: 20px; - position: relative; - z-index:10; - width: 265px; -} - -.cover_boxes ul li .box .thumb img{ - display: block; - position: relative; - max-width: 100%; -} - -.cover_boxes ul li .box .box_content{ - bottom: 0px; - left: 285px; - position: absolute; - padding: 0px 0px 0px 0px; - width: 245px; - z-index:9; - top: 0; -} - -.cover_boxes ul li .box h3{ - margin: 0px 0px 18px 0px; -} - -.cover_boxes ul li .box .qbutton, -.cover_boxes ul li .box h5{ - margin: 20px 0px 0px 0px; -} - -/********* Cover Boxes end style **********/ - -/* ========================================================================== - Qode circles styles - ========================================================================== */ - -.q_circles_holder{ - position: relative; - display: inline-block; - width: 100%; - clear: both; - list-style: none; - margin: 0; - padding: 0; -} - -.q_circles_holder:before{ - position: absolute; - left: 80px; - display: block; - width: 85%; - height: 0; - border-top: 1px solid #eaeaea; - content: ""; -} - -.q_circles_holder.three_columns:before{ - top: 115px; -} - -.q_circles_holder.four_columns:before{ - top: 90px; -} - -.q_circles_holder.five_columns:before{ - top: 82px; -} - -.q_circles_holder.no_line:before{ - display: none; - border: 0; - height: 0; - width: 0; -} - -.q_circles_holder .q_circle_outer{ - position: relative; - float: left; - padding: 0; - margin: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - -o-box-sizing: border-box; -} - -.q_circles_holder.three_columns .q_circle_outer{ - width: 33.3%; -} - -.q_circles_holder.four_columns .q_circle_outer{ - width: 25%; -} - -.q_circles_holder.five_columns .q_circle_outer{ - width: 20%; -} - -.q_circles_holder .q_circle_inner{ - position: relative; - display: table; - vertical-align: middle; - text-align: center; - margin: 0 auto; -} - -.q_circles_holder.three_columns .q_circle_inner{ - width: 230px; - height: 230px; -} - -.q_circles_holder.four_columns .q_circle_inner{ - width: 180px; - height: 180px; -} - -.q_circles_holder.five_columns .q_circle_inner{ - width: 161px; - height: 161px; -} -.q_circles_holder.five_columns .q_circle_inner.big_border{ - width: 177px; - height: 177px; -} -.q_circles_holder .q_circle_inner2 { - position: relative; - display: table-cell; - width: 100%; - height: 100%; - vertical-align: middle; - text-align: center; - background-color: #e3e3e3; - border: 1px solid #f0f0f0; - border-radius: 1000px; - -webkit-border-radius: 1000px; - -moz-border-radius: 1000px; - -o-border-radius: 1000px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - -o-box-sizing: border-box; - overflow: hidden; -} - -.q_circles_holder .q_circle_inner2 img { - display: block; - width: 100%; - border-radius: 1000px; - -webkit-border-radius: 1000px; - -moz-border-radius: 1000px; - -o-border-radius: 1000px; -} - -.q_circles_holder .q_circle_inner2 i, -.q_circles_holder .q_circle_inner2, -.q_circles_holder .q_circle_inner2 .q_text_in_circle { - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; -} - -.q_circles_holder .q_circle_inner2 i{ - color: #b9b9b9; -} - -.q_circles_holder .q_circle_inner2:hover { - background-color: #1abc9c !important; - border-color: #1abc9c !important; -} - -.q_circles_holder .q_circle_inner2:hover i, -.q_circles_holder .q_circle_inner2:hover .q_text_in_circle{ - color: #fff !important; -} - -.q_circles_holder .q_circle_text_holder{ - display: block; - text-align: center; - margin: 36px 0 0; - padding:0 10px; -} - -.q_circles_holder .q_circle_text_holder .q_circle_text{ - display: block; - margin: 7px 0 0; -} -/* ========================================================================== - End of Qode circles styles - ========================================================================== */ - -/******** Content Menu - Start ********/ - -nav.content_menu{ - position: relative; - text-align: left; - display: block; - z-index: 1001; - background-color: #ffffff; - -webkit-transform: translateZ(0px); - width: 100%; - -webkit-transition: left .33s cubic-bezier(0.694,0.0482,0.335,1); - -moz-transition: left .33s cubic-bezier(0.694,0.0482,0.335,1); - -o-transition: left .33s cubic-bezier(0.694,0.0482,0.335,1); - -ms-transform: left .33s cubic-bezier(0.694,0.0482,0.335,1); -} - -.full_width nav.content_menu.fixed { - left: 0; -} - -.right_side_menu_opened .full_width nav.content_menu.fixed { - left: -270px; -} - -.container_inner nav.content_menu{ - width: 1100px; -} -.container_inner nav.content_menu.fixed{ - -moz-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.11); - -webkit-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.11); - box-shadow: 0 4px 4px -4px rgba(0,0,0,0.11); -} -nav.content_menu ul{ - width: 1100px; - margin: 0px auto; - position: relative; - list-style: none outside none; - padding: 0px; - text-align: center; - -webkit-backface-visibility: hidden; -} - -nav.content_menu ul li{ - display: inline-block; - padding: 0px; - text-align: center; - position: relative; - -webkit-backface-visibility: hidden; -} - -nav.content_menu ul li .arrow{ - background-image: url("img/content_menu_arrow.png"); - background-position: 0px 0px; - background-repeat: no-repeat; - display: none; - width: 11px; - height: 7px; - position: absolute; - left: 50%; - margin: -1px 0px 0px -5px; - -webkit-backface-visibility: hidden; -} - -nav.content_menu.fixed ul li.active .arrow{ - display: none; -} - -nav.content_menu ul li a{ - color: #c3c3c3; - font-size: 13px; - text-decoration: none; - display: inline-block; - position: relative; - cursor: pointer; - padding: 21px 20px; - margin: 0px; -} -nav.content_menu ul li a span{ - display: block; - width: 100%; - text-transform: uppercase; - letter-spacing: 1px; - line-height: 18px; - padding: 12px 0 0 0; - font-weight: 600; -} -nav.content_menu ul li i{ - color: #c3c3c3; - margin: 4px 0px 0px 0px; - font-size:24px; - line-height: 1em; - display: block; -} - -nav.content_menu ul li i.undefined{ - display: none; -} - -nav.content_menu ul li.active:hover i, -nav.content_menu ul li:hover i, -nav.content_menu ul li.active:hover a, -nav.content_menu ul li:hover a{ - color: #1abc9c; -} -nav.content_menu ul li.active i, -nav.content_menu ul li.active a{ - color: #303030; -} -nav.content_menu .nav_select_menu{ - display: none; - border: 1px solid #eaeaea; -} - -nav.content_menu .nav_select_menu .nav_select_button{ - cursor: pointer; - display: block; - height: 40px; - position: relative; - width: 40px; - line-height: 40px; - text-align: center; - float: right; -} - -nav.content_menu .nav_select_menu ul{ - display: none; - border: 0px; - width: 100%; - position: relative; - top: 0px; - text-align: left; - padding: 0px 0px 10px 0px; - float: left; - z-index: 100; - zoom:1; -} - -nav.content_menu .nav_select_menu ul li{ - display: block; - border: 0px; - float: none; - padding: 0px; - margin: 0px; - text-align: left; - position: relative; - -webkit-backface-visibility: hidden; -} - -nav.content_menu .nav_select_menu ul li a{ - line-height: 30px; -} - -nav.content_menu .nav_select_menu ul li a i{ - width: 12px; - text-align: center; -} - -.boxed nav.content_menu.fixed{ - padding: 0px; - width: 1100px; -} - -/******** Content Menu - End ********/ - -/******** Visual Composer - Start ********/ - -.section_inner_margin, -.parallax_section_inner_margin -{ - margin-left: -15px; - margin-right: -15px; -} - -/******** Visual Composer - End ********/ -/* ========================================================================== - Contact form 7 styles - ========================================================================== */ -.wpcf7 form.wpcf7-form p { - margin-bottom: 20px; -} - -input.wpcf7-form-control.wpcf7-text, -input.wpcf7-form-control.wpcf7-number, -input.wpcf7-form-control.wpcf7-date, -textarea.wpcf7-form-control.wpcf7-textarea, -select.wpcf7-form-control.wpcf7-select { - width: 100%; -} - -input.wpcf7-form-control.wpcf7-text, -input.wpcf7-form-control.wpcf7-number, -input.wpcf7-form-control.wpcf7-date, -textarea.wpcf7-form-control.wpcf7-textarea, -select.wpcf7-form-control.wpcf7-select, -input.wpcf7-form-control.wpcf7-quiz { - margin: 5px 0 0; - padding: 15px; - border: 0; - outline: 0; - resize: none; - font-size: 13px; - line-height: 17px; - background-color: #fff; - color: #818181; - font-family: 'Raleway'; - font-weight: 400; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -input.wpcf7-form-control.wpcf7-quiz { - margin-left: 15px; -} - -span.wpcf7-form-control-wrap .wpcf7-form-control.wpcf7-checkbox input[type="checkbox"], -span.wpcf7-form-control-wrap .wpcf7-form-control.wpcf7-radio input[type="radio"] { - position: relative; - top: 2px; -} - -span.wpcf7-form-control-wrap .wpcf7-form-control.wpcf7-checkbox input[type="checkbox"] { - margin-left: 5px; -} - -input.wpcf7-form-control.wpcf7-submit { - position: relative; - display: inline-block; - width: auto; - height: 39px; - line-height: 36px; - margin: 0; - padding: 0px 23px; - - font-size: 13px; - font-weight: 700; - font-family: 'Raleway', sans-serif; - text-align: left; - - text-decoration: none; - cursor: pointer; - white-space: nowrap; - outline: none; - font-style: normal; - text-transform: uppercase; - letter-spacing: 1px; - - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - background-color: transparent; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -ms-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - - -webkit-box-sizing: initial; - -moz-box-sizing: initial; - box-sizing: initial; -} - -input.wpcf7-form-control.wpcf7-submit[disabled] { - color: #818181; - border: 2px solid #818181; - cursor: not-allowed; -} - -input.wpcf7-form-control.wpcf7-submit:not([disabled]) { - border: 2px solid #303030; - color: #303030; -} - -input.wpcf7-form-control.wpcf7-submit:not([disabled]):hover { - background-color: #1abc9c; - border-color: #1abc9c; - color: #fff; - text-decoration: none; -} - -input.wpcf7-form-control.wpcf7-range { - width: 100%; -} - -div.wpcf7-response-output { - position: relative; - padding: 17px 30px 17px 55px; - color: #fff; - text-transform: uppercase; - font-weight: 500; - margin-left: 0; - margin-right: 0; - font-weight: 500; - font-size: 15px; - text-transform: uppercase; - letter-spacing: 1px; - border: none; -} - -div.wpcf7-response-output:before { - font-family: 'FontAwesome', sans-serif; - width: 20px; - height: 20px; - display: inline-block; - color: #fff; - position: absolute; - left: 25px; -} - -div.wpcf7-response-output.wpcf7-mail-sent-ok { - background-color: #1abc9c; -} - -div.wpcf7-response-output.wpcf7-mail-sent-ok:before { - content: "\f087"; -} - -div.wpcf7-response-output.wpcf7-validation-errors { - background-color: #f1c40f; -} - -div.wpcf7-response-output.wpcf7-validation-errors:before { - content: "\f12a"; -} - -.two_columns_form_without_space, -.two_columns_form_with_space{ - display: table; -} - -.two_columns_form_with_space input.wpcf7-form-control.wpcf7-text, -.two_columns_form_without_space input.wpcf7-form-control.wpcf7-text{ - margin: 0; -} - -.two_columns_form_without_space .column_left { - display: table-cell; - vertical-align: top; -} - -.two_columns_form_without_space .column_right { - display: table-cell; - width: 1%; - text-align: left; - vertical-align: top; -} - -.two_columns_form_with_space .column_left { - display: table-cell; - vertical-align: top; - padding-right: 5px; -} - - -.two_columns_form_with_space .column_right { - display: table-cell; - width: 1%; - vertical-align: top; - padding-left: 5px; -} - -/* ========================================================================== - End Contact form 7 styles - ========================================================================== */ - - - -/* ========================================================================== -Gravity forms styles -========================================================================== */ - -body .gform_wrapper .gform_fields .gfield{ - margin: 0 0 20px 0; -} - -body .gform_wrapper .gf_progressbar, -body .gform_wrapper .gf_progressbar_wrapper, -body .gform_wrapper .top_label input.large, -body .gform_wrapper .top_label select.large, -body .gform_wrapper .top_label textarea.textarea { - /*width: 100%;*/ -} - -body .gform_wrapper .gf_progressbar_percentage, -body .gform_wrapper .gf_step, -body .gform_wrapper .gf_step span.gf_step_number, -body .gform_wrapper .gfield_description, -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper input[type="button"], -body .gform_wrapper input[type="submit"], -body .gform_wrapper input[type="reset"], -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single, -body .gform_wrapper select { - font-family: 'Raleway', sans-serif; -} - -body .gform_wrapper .gf_progressbar, -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-drop, -body .gform_wrapper .chzn-container-multi .chzn-drop, -body .gform_wrapper .chzn-container-active .chzn-single, -body .gform_wrapper .chzn-container-active .chzn-choices { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -body .gform_wrapper .gf_progressbar, -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single, -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper .chzn-container-single .chzn-single div, -body .gform_wrapper .chzn-container-single .chzn-single b, -body .gform_wrapper .chzn-container .chzn-drop, -body .gform_wrapper .chzn-choices, -body .gform_wrapper .chzn-container-multi .chzn-choices, -body .gform_wrapper li.gfield.gfield_error, -body .gform_wrapper li.gfield.gfield_error.gfield_contains_required.gfield_creditcard_warning, -body .gform_wrapper select{ - border: 0; -} - -body .gform_wrapper .gf_progressbar, -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single{ - background-image: none; -} - -body .gform_wrapper .top_label .gfield_label, -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper .ginput_left input:focus+label, -body .gform_wrapper .ginput_right input:focus+label, -body .gform_wrapper .ginput_full input:focus+label, -body .gform_wrapper table.gfield_list thead th { - font-weight: 400; -} - -body .gform_wrapper .charleft{ - margin-top: 0; -} - -body .gform_wrapper .gfield_description { - padding: 5px 0 0 0; -} - -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper select, -body .gform_wrapper.gf_browser_chrome .ginput_complex select, -body .gform_wrapper.gf_browser_chrome .ginput_complex .ginput_right select { - padding: 15px; - outline: 0; - resize: none; - box-sizing: border-box; -} - -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper input[type="button"], -body .gform_wrapper input[type="submit"], -body .gform_wrapper input[type="reset"], -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single, -body .gform_wrapper select{ - font-size: 13px; -} - -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single { - line-height: 17px; -} - -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single b { - background-color: #ffffff; -} - -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper .chzn-container-single .chzn-single span, -body .gform_wrapper select{ - color: #818181; -} - -body .gform_wrapper input[type=text], -body .gform_wrapper input[type=url], -body .gform_wrapper input[type=email], -body .gform_wrapper input[type=tel], -body .gform_wrapper input[type=number], -body .gform_wrapper input[type=password], -body .gform_wrapper textarea, -body .gform_wrapper .chzn-container, -body .gform_wrapper select{ - margin: 5px 0 0; -} - -body .gform_wrapper input[type="button"], -body .gform_wrapper input[type="submit"], -body .gform_wrapper input[type="reset"]{ - position: relative; - display: inline-block; - width: auto; - height: 39px; - line-height: 36px; - margin: 0; - padding: 0px 23px; - border: 2px solid #303030; - font-weight: 700; - text-align: left; - color: #303030; - text-decoration: none; - cursor: pointer; - white-space: nowrap; - outline: none; - font-style: normal; - text-transform: uppercase; - letter-spacing: 1px; - - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - background-color: transparent; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -ms-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; -} - -body .gform_wrapper input[type="button"]:hover, -body .gform_wrapper input[type="submit"]:hover, -body .gform_wrapper input[type="reset"]:hover{ - background-color: #1abc9c; - border-color: #1abc9c; - color: #ffffff; - text-decoration: none; -} - -body .gform_wrapper .chzn-container .chzn-single, -body .gform_wrapper .chzn-container-single .chzn-single { - height: auto; - padding: 15px 2%; -} - -body .gform_wrapper .chzn-container-single .chzn-single div b{ - background-position: -18px 10px; -} - -body .gform_wrapper .chzn-container-single .chzn-single-with-drop div b{ - background-position: -1px 10px; -} - -body .gform_wrapper .chzn-container-single .chzn-search input{ - border: 1px solid #aaaaaa; -} - - -body .gform_wrapper .chzn-choices{ - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ffffff), color-stop(0, #ffffff)) !important; -} - -body .gform_wrapper .chzn-choices .search-field .default{ - padding-left: 10%; -} - -body .gform_wrapper .chzn-container-multi .chzn-choices .search-field input { - padding: 15px; -} - -body .gform_wrapper div.validation_error, -body .gform_wrapper .gform_confirmation_message { - position: relative; - padding: 17px 30px 17px 30px; - color: #fff; - text-transform: uppercase; - margin-left: 0; - margin-right: 0; - font-weight: 500; - font-size: 15px; - text-transform: uppercase; - letter-spacing: 1px; - border: none; -} - -body .gform_wrapper div.validation_error { - background-color: #f1c40f; -} - -body .gform_wrapper .gform_confirmation_message{ - background-color: #1abc9c; -} - -body .gform_wrapper .ginput_complex .name_prefix, -body .gform_wrapper .ginput_complex .name_suffix, -body .gform_wrapper input.ginput_quantity{ - width: 60px !important; -} - -body .gform_wrapper .datepicker { - width: 105px !important; -} - -body .gform_wrapper .gfield_time_ampm select { - min-width: 80px; -} - -body .gform_wrapper .gfield_time_hour{ - vertical-align: middle; -} - -body .gform_wrapper .button.gform_button_select_files{ - height: 31px; - line-height: 24px; - padding: 0 9px; - font-size: 12px; - margin-left: 10px; -} - -/* ========================================================================== -End Gravity forms styles -========================================================================== */ - -/* ========================================================================== - Vertical menu styles - ========================================================================== */ - -.vertical_menu_enabled .q_slider, -.vertical_menu_enabled .full_width, -.vertical_menu_enabled .content .container, -.vertical_menu_enabled .title_outer, -.vertical_menu_enabled footer{ - padding-left: 260px; -} - -.boxed.vertical_menu_enabled .q_slider, -.boxed.vertical_menu_enabled .full_width, -.boxed.vertical_menu_enabled .content .container, -.boxed.vertical_menu_enabled .title_outer, -.boxed.vertical_menu_enabled footer{ - padding-left: 0px; -} - -.boxed.vertical_menu_enabled, -.boxed.vertical_menu_enabled footer.uncover{ - padding-left: 260px; -} - -.vertical_menu_enabled .content .title .container{ - padding-left: 0px; -} - -.vertical_menu_enabled .content .container, -.vertical_menu_enabled .q_slider, -.vertical_menu_enabled footer{ - width: auto; -} - -aside.vertical_menu_area { - position: fixed; - width: 260px; - top: 0; - left: 0; - padding:10px 30px; - background-color: #fff; - height: 100%; - z-index: 101; - -webkit-backface-visibility:hidden; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: background-color 0.3s ease; - -moz-transition: background-color 0.3s ease; - -o-transition: background-color 0.3s ease; - -ms-transition: background-color 0.3s ease; - transition: background-color 0.3s ease; - outline: none; -} - -aside.vertical_menu_area.with_scroll { - overflow: hidden; -} - -aside.vertical_menu_area .vertical_menu_area_widget_holder{ - font-size:13px; - position: relative; -} -.vertical_menu_enabled.vertical_area_transparent .content{ - padding-left: 0px; -} - -.vertical_menu_transparency_on aside.vertical_menu_area.light .vertical_menu_area_widget_holder, -.vertical_menu_transparency_on aside.vertical_menu_area.light .widget a, -.vertical_menu_transparency_on aside.vertical_menu_area.light .q_social_icon_holder i.simple_social{ - color: #fff; -} - -.vertical_menu_transparency_on aside.vertical_menu_area.dark .vertical_menu_area_widget_holder, -.vertical_menu_transparency_on aside.vertical_menu_area.dark .widget a, -.vertical_menu_transparency_on aside.vertical_menu_area.dark .q_social_icon_holder i.simple_social{ - color: #000; -} - -.vertical_menu_enabled header{ - display: block; -} - -.vertical_menu_enabled header .header_inner{ - display: none; -} - -.vertical_area_background{ - position: fixed; - width: 260px; - height: 100%; - background-position: right top; - background-repeat: no-repeat; - background-size: cover; - top: 0px; - left: 0px; - z-index: 0; - -webkit-transition: opacity 0.6s ease; - -moz-transition: opacity 0.6s ease; - -o-transition: opacity 0.6s ease; - -ms-transition: opacity 0.6s ease; - transition: opacity 0.6s ease; - opacity: 1; -} - -.vertical_logo_wrapper{ - z-index: 100; - position: relative; -} - -.vertical_logo_wrapper img{ - max-width: 100%; - position: absolute; - top: 0px; - left: 0px; - -webkit-transition: opacity 0.3s ease; - -moz-transition: opacity 0.3s ease; - -o-transition: opacity 0.3s ease; - -ms-transition: opacity 0.3s ease; - transition: opacity 0.3s ease; -} - -.q_logo_vertical img.normal{ - position: relative; -} - -.q_logo_vertical img.light, -.q_logo_vertical img.dark{ - opacity: 0; -} - -.vertical_menu_transparency_on .light .q_logo_vertical img.normal{ - opacity:0; -} - -.vertical_menu_transparency_on .light .q_logo_vertical img.light{ - opacity:1; -} - -.vertical_menu_transparency_on .light .q_logo_vertical img.dark{ - opacity:0; -} - -.vertical_menu_transparency_on .dark .q_logo_vertical img.normal{ - opacity:0; -} - -.vertical_menu_transparency_on .dark .q_logo_vertical img.light{ - opacity:0; -} - -.vertical_menu_transparency_on .dark .q_logo_vertical img.dark{ - opacity:1; -} - -nav.vertical_menu { - position: relative; - z-index: 101; - margin: 45px 0 0 0; -} - -.vertical_menu ul{ - list-style: none; -} - -.vertical_menu ul li{ - position: relative; -} - -nav.vertical_menu > ul > li > a { - position: relative; - color: #303030; - font-size: 13px; - font-weight: 700; - letter-spacing: 1px; - text-decoration: none; - text-transform: uppercase; - display: block; - position: relative; - line-height: 34px; - padding: 0 0px; - margin: 0; - cursor: pointer; - -webkit-transition: color 0.3s ease; - -moz-transition: color 0.3s ease; - -o-transition: color 0.3s ease; - -ms-transition: color 0.3s ease; - transition: color 0.3s ease; -} - -.vertical_menu_transparency_on .light nav.vertical_menu > ul > li > a{ - color: #ffffff; -} - -.vertical_menu_transparency_on .dark nav.vertical_menu > ul > li > a{ - color: #000000; -} - -.vertical_menu .second .inner{ - position: relative; - display: block; - padding: 0; - z-index: 997; -} - -.vertical_menu_toggle .second .inner_arrow, -.vertical_menu_on_click .second .inner_arrow, -.vertical_menu_float .second .inner_arrow{ - display: none; -} - -.vertical_menu .second .inner > ul > li > a:hover{ - color: #303030; -} - -.vertical_menu_toggle .second, -.vertical_menu_on_click .second{ - margin: 0px; - display: none; - overflow: hidden; - z-index: 10; -} - -.vertical_menu_toggle .second ul ul, -.vertical_menu_on_click .second ul ul{ - display: none; -} -nav.vertical_menu_toggle ul li a, -nav.vertical_menu_on_click ul li a{ - display: block; -} -nav.vertical_menu_toggle ul li a .line, -nav.vertical_menu_on_click ul li a .line{ - display: none; -} - -nav.vertical_menu_toggle ul > li.menu-item-has-children > a > .plus, -nav.vertical_menu_on_click ul > li.menu-item-has-children > a > .plus, -nav.vertical_menu_float ul > li.menu-item-has-children > a > .plus{ - float: right; - width: 20px; - height: 8px; - margin: 12px 0 0 0; - z-index: 10000; - display: block; - position: relative; - background-image: url('img/vertical_menu_cross.png'); - background-repeat: no-repeat; - background-position: 100%; - -o-background-size: 8px 8px; - -webkit-background-size: 8px 8px; - -moz-background-size: 8px 8px; - background-size: 8px 8px; -} - -nav.vertical_menu_toggle ul li ul > li.menu-item-has-children > a > .plus, -nav.vertical_menu_on_click ul li ul > li.menu-item-has-children > a > .plus, -nav.vertical_menu_float ul li ul > li.menu-item-has-children > a > .plus{ - margin: 5px 0 0 0; -} - -.no-touch nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, -.no-touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, -.no-touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus{ - background-image: url('img/vertical_menu_minus.png'); -} - -.touch nav.vertical_menu_toggle ul > li.menu-item-has-children.open > a > .plus, -.touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, -.touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { - background-image: url('img/vertical_menu_minus.png'); -} - -nav.vertical_menu_toggle ul li.menu-item-has-children a span, -nav.vertical_menu_on_click ul li.menu-item-has-children a span, -nav.vertical_menu_float ul li.menu-item-has-children a span{ - display: inline-block; - max-width: 180px; -} - -.vertical_menu_float .menu-item .second { - position: absolute; - top: 0; - left: calc(100% + 30px); /*because of the padding*/ - width: 100%; - margin-left: 50px; - opacity: 0; - background-color: #fff; - visibility: hidden; - transition: all 0.3s ease-in-out; -} - -.vertical_menu_float .menu-item .second *{ - visibility: hidden; - transition: visibility 0.3s ease-in-out; -} - -.vertical_menu_float .menu-item .second.vertical_menu_start { - margin-left: 0px; - opacity: 1; - visibility: visible; -} - -.vertical_menu_float .menu-item .second.vertical_menu_start *{ - visibility: visible; -} - - -.vertical_menu_float .menu-item .second.vertical_menu_start ul li ul, -.vertical_menu_float .menu-item .second.vertical_menu_start ul li ul *{ - visibility:hidden; -} - -.vertical_menu_float .menu-item .second.vertical_menu_start ul li ul.vertical_submenu_start, -.vertical_menu_float .menu-item .second.vertical_menu_start ul li ul.vertical_submenu_start *{ - visibility:visible; -} - -.vertical_menu_float .second .inner ul{ - width: 100%; -} - -.vertical_menu_float li.narrow .second .inner ul{ /*because of the .narrow styling*/ - border: none; - background-color: #fff; - padding: 0; -} - -.vertical_menu_float .second .inner ul li ul { - position: absolute; - border:none; - top: 0; - left: 100%; - margin-left: 50px; - height: auto; - visibility: hidden; - width: 100%; - opacity: 0; - overflow: hidden; - z-index: 10; - background-color: #fff; - padding: 0; - transition: all 0.3s ease-in-out; -} - -.vertical_menu_float .second .inner ul li ul.vertical_submenu_start{ - opacity: 1; - margin-left:0; - visibility: visible; -} - -.vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area .vertical_menu_float .second .inner ul li ul, -.vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area .vertical_menu_float .menu-item .second { - background-color: transparent !important; -} - - -.vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a > .plus, -.vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children > a > .plus, -.vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children > a > .plus{ - background-image: url('img/vertical_menu_cross_white.png'); -} - -.vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, -.vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, -.vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus{ - background-image: url('img/vertical_menu_minus_white.png'); -} - -.vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a > .plus, -.vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children > a > .plus, -.vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children > a > .plus{ - background-image: url('img/vertical_menu_cross_black.png'); -} - -.vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, -.vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, -.vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus{ - background-image: url('img/vertical_menu_minus_black.png'); -} - -@media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { - nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, - nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, - nav.vertical_menu_float ul li.menu-item-has-children a .plus{ - background-image: url('img/vertical_menu_cross@1_5x.png'); - } - .no-touch nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, - .no-touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .no-touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus - { - background-image: url('img/vertical_menu_minus@1_5x.png'); - } - - .touch nav.vertical_menu_toggle ul > li.menu-item-has-children.open > a > .plus, - .touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { - background-image: url('img/vertical_menu_minus@1_5x.png'); - } - - .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_float ul li.menu-item-has-children a .plus{ - background-image: url('img/vertical_menu_cross_white@1_5x.png'); - } - .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus - { - background-image: url('img/vertical_menu_minus_white@1_5x.png'); - } - - .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_float ul li.menu-item-has-children a .plus{ - background-image: url('img/vertical_menu_cross_black@1_5x.png'); - } - .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus - { - background-image: url('img/vertical_menu_minus_black@1_5x.png'); - } - -} -@media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { - nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, - nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, - nav.vertical_menu_float ul li.menu-item-has-children a .plus{ - background-image: url('img/vertical_menu_cross@2x.png'); - } - - .no-touch nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, - .no-touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .no-touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus - { - background-image: url('img/vertical_menu_minus@2x.png'); - } - - .touch nav.vertical_menu_toggle ul > li.menu-item-has-children.open > a > .plus, - .touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { - background-image: url('img/vertical_menu_minus@2x.png'); - } - - .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_float ul li.menu-item-has-children a .plus{ - background-image: url('img/vertical_menu_cross_white@2x.png'); - } - .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus - { - background-image: url('img/vertical_menu_minus_white@2x.png'); - } - - .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_float ul li.menu-item-has-children a .plus{ - background-image: url('img/vertical_menu_cross_black@2x.png'); - } - .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, - .vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus - { - background-image: url('img/vertical_menu_minus_black@2x.png'); - } -} - -nav.vertical_menu_toggle ul li a .q_menu_arrow, -nav.vertical_menu_on_click ul li a .q_menu_arrow, -nav.vertical_menu_float ul li a .q_menu_arrow{ - display: none; -} -nav.vertical_menu_toggle li.narrow .second .inner ul, -nav.vertical_menu_on_click li.narrow .second .inner ul{ - background-color: transparent; - padding:0; - width: 100%; -} -nav.vertical_menu_toggle li.narrow .second .inner ul ul, -nav.vertical_menu_on_click li.narrow .second .inner ul ul{ - display: none; -} -.vertical_menu_toggle .second .inner ul li a, -.vertical_menu_on_click .second .inner ul li a, -.vertical_menu_float .second .inner ul li a{ - display: block; - height: auto; - font-family: inherit; - font-size: 13px; - line-height: 18px; - color: #818181; - margin: 0; - padding: 5px 0px 5px 0px; - text-decoration: none; - -webkit-transition: color 0.3s ease; - -moz-transition: color 0.3s ease; - -o-transition: color 0.3s ease; - -ms-transition: color 0.3s ease; - transition: color 0.3s ease; -} - -.vertical_menu_transparency_on .light .vertical_menu_toggle .second .inner ul li a, -.vertical_menu_transparency_on .light .vertical_menu_on_click .second .inner ul li a, -.vertical_menu_transparency_on .light .vertical_menu_float .second .inner ul li a{ - color: #ffffff; -} - -.vertical_menu_transparency_on .dark .vertical_menu_toggle .second .inner ul li a, -.vertical_menu_transparency_on .dark .vertical_menu_on_click .second .inner ul li a, -.vertical_menu_transparency_on .dark .vertical_menu_float .second .inner ul li a{ - color: #000000; -} - -.vertical_menu_toggle .second .inner ul ul li a, -.vertical_menu_on_click .second .inner ul ul li a, -.vertical_menu_float .second .inner ul li a{ - padding-left: 15px; - padding-right: 15px; -} -.vertical_menu_area_widget_holder{ - margin:60px 0 0 0; -} -.vertical_menu_enabled .carousel-inner:not(.relative_position){ - left: 260px !important; - -} - -.vertical_menu_area .q_social_icon_holder{ - margin: 0 8px 2px 0 !important; -} -.vertical_menu_enabled .content{ - margin-top:0 !important; - padding-top:0 !important; - -} -.boxed.vertical_menu_enabled .carousel-inner{ - width: 1150px !important; - left: auto !important; -} - -.vertical_menu_enabled.vertical_menu_transparency .full_section_inner{ - overflow: hidden; -} - -.vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area{ - background-color: transparent !important; -} - -.vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area .vertical_area_background{ - -webkit-transition: opacity 0.3s ease; - -moz-transition: opacity 0.3s ease; - -o-transition: opacity 0.3s ease; - -ms-transition: opacity 0.3s ease; - transition: opacity 0.3s ease; - opacity: 0 !important; -} - -.vertical_menu_enabled.vertical_menu_transparency .q_slider{ - padding-left: 0px; -} - -.vertical_menu_enabled.vertical_menu_enabled.vertical_menu_transparency .carousel-inner:not(.relative_position){ - left: 0px !important; -} - -.boxed.vertical_menu_enabled.vertical_menu_enabled.vertical_menu_transparency .carousel-inner:not(.relative_position){ - left: auto !important; -} - -.vertical_menu_enabled.vertical_menu_transparency .carousel-control.left{ - bottom: 60px; - height: 44px; - right: 105px; - top: auto; - width: 44px; -} - -.vertical_menu_enabled.vertical_menu_transparency .carousel-control.right{ - bottom: 60px; - height: 44px; - right: 50px; - top: auto; - width: 44px; -} - -.vertical_menu_enabled.vertical_menu_transparency .carousel-control .prev_nav { - left: 0; - margin: 0 !important; - top: 0; - height: 40px; - width: 40px; - line-height: 40px; -} - -.vertical_menu_enabled.vertical_menu_transparency .carousel-control .next_nav { - margin: 0 !important; - right: 0; - top: 0; - height: 40px; - width: 40px; - line-height: 40px; -} - -.vertical_menu_enabled.vertical_menu_transparency .carousel-control i { - font-size: 24px; - line-height: 40px; -} - -.vertical_menu_enabled.vertical_menu_transparency .carousel-indicators{ - display: none !important; -} - -.vertical_menu_enabled.page-template-landing_page-php .q_slider, -.vertical_menu_enabled.page-template-landing_page-php .full_width, -.vertical_menu_enabled.page-template-landing_page-php .content .container, -.vertical_menu_enabled.page-template-landing_page-php .title_outer, -.boxed.vertical_menu_enabled.page-template-landing_page-php, -.vertical_menu_enabled.page-template-landing_page-php .full_screen_holder{ - padding-left: 0px !important; -} - -.vertical_menu_enabled.page-template-landing_page-php .carousel-inner:not(.relative_position){ - left: 0px !important; -} - -/* vertical menu - hidden type START */ - -.vertical_menu_hidden aside.vertical_menu_area{ - -webkit-box-shadow: 0px 0px 2px 2px rgba(0,0,0,.15); - box-shadow: 0px 0px 2px 2px rgba(0,0,0,.15); - left: -220px; - padding: 10px 40px; - -webkit-transition: left 0.15s ease-out; - -moz-transition: left 0.15s ease-out; - -o-transition: left 0.15s ease-out; - -ms-transform: left 0.15s ease-out; - transition: left 0.15s ease-out; -} - -.vertical_menu_hidden .vertical_area_background{ - left: -220px; - -webkit-transition: left 0.15s ease-out; - -moz-transition: left 0.15s ease-out; - -o-transition: left 0.15s ease-out; - -ms-transform: left 0.15s ease-out; - transition: left 0.15s ease-out; -} - - -.vertical_menu_hidden.vertical_menu_hidden_with_logo aside.vertical_menu_area, -.vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_area_background { - left: -190px; -} - -.vertical_menu_hidden aside.vertical_menu_area.active, -.vertical_menu_hidden aside.vertical_menu_area.active .vertical_area_background{ - left: 0px; -} - -.vertical_menu_enabled.vertical_menu_hidden .full_screen_holder, -.vertical_menu_enabled.vertical_menu_hidden .q_slider, -.vertical_menu_enabled.vertical_menu_hidden .full_width, -body.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_hidden .content .full_width, -.vertical_menu_enabled.vertical_menu_hidden .content .container, -.vertical_menu_enabled.vertical_menu_hidden .title_outer, -.vertical_menu_enabled.vertical_menu_hidden footer, -.boxed.vertical_menu_enabled.vertical_menu_hidden, -.boxed.vertical_menu_enabled.vertical_menu_hidden footer.uncover, -.vertical_menu_enabled.vertical_menu_hidden .full_screen_holder{ - padding-left: 40px; -} - -.vertical_menu_enabled.vertical_menu_hidden .carousel-inner:not(.relative_position){ - left: 40px !important; -} - -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .full_screen_holder, -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .q_slider, -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .full_width, -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .content .container, -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .title_outer, -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo footer, -.boxed.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo, -.boxed.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo footer.uncover, -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .full_screen_holder{ - padding-left: 70px; -} - -.vertical_menu_enabled.vertical_menu_hidden .carousel-control .prev_nav, -.vertical_menu_enabled.vertical_menu_hidden .carousel-control .next_nav{ - margin-top: -27px !important; -} - -.vertical_menu_hidden_button{ - position: fixed; - top: 0; - left: 0px; - width: 40px; - height: 40px; - z-index: 11; - display: block; -} - -.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_hidden_button { - width: 70px; - height: 40px; - z-index: 1000; -} - -.vertical_menu_hidden_button_line { - position: absolute; - top: 50%; - left: 50%; - font-size: 30px; - display: block; - margin-left: -11px; - width: 22px; - height: 3px; - background: #303030; -} -.vertical_menu_hidden_button_line:after,.vertical_menu_hidden_button_line:before{ - content: ''; - position: absolute; - width: 100%; - height: 3px; - background: #303030; - left: 0; - -webkit-transform-origin:center center; - -moz-transform-origin:center center; - -ms-transform-origin:center center; - -o-transform-origin:center center; - transform-origin:center center; -} -.vertical_menu_hidden_button_line:before{ - top: -6px; -} -.vertical_menu_hidden_button_line:after{ - bottom: -6px; -} - -.vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line{ - background: rgba(220, 151, 31,0); -} -.vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:after{ - -webkit-transform: rotate(-45deg) translate(2px,-8px); - -moz-transform: rotate(-45deg) translate(3px,-8px); - -ms-transform: rotate(-45deg) translate(3px,-8px); - -o-transform: rotate(-45deg) translate(3px,-8px); - transform: rotate(-45deg) translate(3px,-8px); -} - -.vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:before{ - -webkit-transform: rotate(45deg) translate(4px,9px); - -moz-transform: rotate(45deg) translate(3px,8px); - -ms-transform: rotate(45deg) translate(3px,8px); - -o-transform: rotate(45deg) translate(3px,8px); - transform: rotate(45deg) translate(3px,8px); - -} -.vertical_menu_hidden_button_line, -.vertical_menu_hidden_button_line:before, -.vertical_menu_hidden_button_line:after{ - -webkit-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); - -moz-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); - -ms-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); - -o-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); - transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); -} - -.vertical_menu_hidden_button:hover .vertical_menu_hidden_button_line:before{ - top: -8px; -} - -.vertical_menu_hidden_button:hover .vertical_menu_hidden_button_line:after{ - bottom: -8px; -} - -.vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:after{ - bottom: -8px; -} -.vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:before{ - top: -8px; -} - -.vertical_menu_hidden .vertical_menu_area_bottom_logo { - position: fixed; - width: 70px; - text-align: center; - bottom: 0px; - z-index: 1000; -} - -.vertical_menu_hidden .vertical_menu_area_bottom_logo_inner { - position: absolute; - bottom: 20px; - box-sizing: border-box; - text-align: center; - width: 100%; -} - -.vertical_menu_hidden .vertical_menu_area_bottom_logo_inner a { - display: block; - padding: 0 10px; -} - -.vertical_menu_hidden .vertical_menu_area_bottom_logo{ - left: 0; - -webkit-transition: left 0.15s ease-in-out; - -moz-transition: left 0.15s ease-in-out; - -ms-transition: left 0.15s ease-in-out; - -o-transition: left 0.15s ease-in-out; - transition: left 0.15s ease-in-out; -} - -.vertical_menu_hidden .vertical_menu_area_bottom_logo.active{ - left: -70px; -} - -.vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_area:not(.active) .vertical_menu_area_inner{ - left: -30px; -} - -.vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_area .vertical_menu_area_inner { - left: 0; -} - -.vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_area .vertical_menu_area_inner { - position: relative; - height: 100%; -} - -/*vertical menu width for initially hidden type*/ - -.vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area, -.vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area .vertical_area_background{ - width:290px; - left:-250px; -} - -.vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area, -.vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area .vertical_area_background{ - width:350px; - left:-310px; -} - -.vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area, -.vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area .vertical_area_background{ - width:400px; - left:-360px; -} - -.vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area.active, -.vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area.active .vertical_area_background, -.vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area.active, -.vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area.active .vertical_area_background, -.vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area.active, -.vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area.active .vertical_area_background{ - left:0; -} - -/*vertical menu width for initially hidden type with logo at bottom */ - -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area .vertical_area_background{ - width:290px; - left:-220px; -} - -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area .vertical_area_background{ - width:350px; - left:-280px; -} - -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area .vertical_area_background{ - width:400px; - left:-330px; -} - -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area.active, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area.active .vertical_area_background, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area.active, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area.active .vertical_area_background, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area.active, -.vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area.active .vertical_area_background{ - left:0; -} - - -/* vertical menu - hidden type END */ - -/* ========================================================================== - End Vertical menu styles - ========================================================================== */ - -/* ========================================================================== - Popup menu start styles - ========================================================================== */ - -.popup_menu_inner{ - display: inline-block; - height: 2px; - position: relative; - top: -1px; - vertical-align: middle; - width: 20px; - position: relative; - width: 20px; -} - -.popup_menu .line{ - background-color: #9D9D9D; - height: 2px; - margin: 0px; - width: 13px; - top: 0px; - left: 0px; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -ms-transform: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - position: absolute; - display: inline-block; -} - -.popup_menu .line:after, .popup_menu .line:before { - background-color: #9D9D9D; - content: ""; - display: block; - height: 2px; - position: absolute; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -ms-transform: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - width: 13px; - z-index: -1; - -webkit-backface-visibility: hidden; /*because X sign jumps on hover in Chrome*/ -} - -@media only screen and (min-width: 1000px) { - - .dark:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line, - .dark:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:before, - .dark:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:after, - .dark.header_style_on_scroll .popup_menu:not(.opened) .line, - .dark.header_style_on_scroll .popup_menu:not(.opened) .line:before, - .dark.header_style_on_scroll .popup_menu:not(.opened) .line:after{ - background-color: #000; - } - - .light:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line, - .light:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:before, - .light:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:after, - .light.header_style_on_scroll .popup_menu:not(.opened) .line, - .light.header_style_on_scroll .popup_menu:not(.opened) .line:before, - .light.header_style_on_scroll .popup_menu:not(.opened) .line:after{ - background-color: #fff; - } - -} - -.popup_menu .line:before { - top: -4px; -} - -.popup_menu .line:after { - top: 4px; -} - -.side_menu_button .popup_menu:hover{ - opacity: 0.8; -} - -.popup_menu.opened .line{ - background-color: transparent !important; -} - -.popup_menu.opened .line:after { - background-color: #ffffff; - top: 0 !important; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -o-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} - -.popup_menu.opened .line:before { - background-color: #ffffff; - top: 0 !important; - -webkit-transform: rotate(-45deg); - -moz-transform: rotate(-45deg); - -o-transform: rotate(-45deg); - -ms-transform: rotate(-45deg); - transform: rotate(-45deg); -} - -.popup_menu_holder_outer{ - position: fixed; - top: 0px; - left: 0px; - width: 100%; - height: 100%; - visibility: hidden; - opacity: 0; - z-index: 105; /* this have to be between header z-index and content z-index */ -} - -.popup_menu_holder{ - width: 100%; - height: 100%; - background-color: rgba(48,48,48,0.95); - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - display: table; -} - -.popup_menu_holder_inner{ - display: table-cell; - vertical-align: middle; - padding: 100px 0px; -} - -.popup_menu_opened .main_menu, -.popup_menu_opened .side_menu_button a:not(.popup_menu), -.popup_menu_opened #back_to_top, -.popup_menu_opened .header_top, -.popup_menu_opened header .tooltip, -.popup_menu_opened .mobile_menu_button, -.popup_menu_opened .fixed_top_header .header_bottom_center_widget, -.popup_menu_opened .fixed_top_header .header_bottom_right_widget_holder{ - visibility: hidden !important; -} - -.popup_menu_opened .header_bottom .container_inner{ - border: none !important; -} - -.popup_menu_opened .side_menu_button .shopping_cart_header{ - display: none; -} - -.popup_menu_opened .popup_menu_holder_outer{ - visibility: visible; - opacity: 1; -} - -.touch .popup_menu_holder_outer{ - display: none; -} - -.touch .popup_menu_opened .popup_menu_holder_outer{ - display: block; -} - -.popup_menu_opened header.scrolled .header_bottom, -.popup_menu_opened header.sticky .header_bottom{ - background-color: transparent !important; - box-shadow: none; -} - -.popup_menu_opened .header_top, -.popup_menu_opened .header_bottom, -.popup_menu_opened .fixed_top_header .top_header{ - background-color: transparent !important; - border: 0px !important; -} - -.popup_menu_opened .q_logo img.normal, -.popup_menu_opened .q_logo img.light, -.popup_menu_opened .q_logo img.sticky, -.popup_menu_opened .q_logo img.dark, -.popup_menu_opened .q_logo img.mobile { - opacity: 0 !important; -} - -.popup_menu_opened header .q_logo img.popup{ - opacity: 1 !important; -} - -nav.popup_menu{ - margin: 0px auto; - position: relative; - top: 0px; - text-align: left; -} - -nav.popup_menu ul{ - display: none; - position: relative; - list-style: none; - padding: 0; - margin: 0; -} - -nav.popup_menu > ul{ - display: block; -} - -nav.popup_menu ul li{ - margin: 0; - padding: 0; - text-align: center; - font-size: 45px; - line-height: 50px; -} - -nav.popup_menu ul li a, -nav.popup_menu ul li h6{ - font-size: 24px; - font-weight: 500; - line-height: 50px; - letter-spacing: 2px; - color: #ffffff; - padding: 0px; - display: block; - position: relative; - text-decoration: none; - text-transform: uppercase; - cursor: pointer; -} - -nav.popup_menu ul li a:hover, -nav.popup_menu ul li h6:hover{ - color: #9c9c9c; -} - -nav.popup_menu ul li a span, -nav.popup_menu ul li h6 span{ - display: inline-block; - vertical-align: middle; -} - - -nav.popup_menu ul li ul li a, -nav.popup_menu ul li ul li h6{ - font-size: 14px; - text-transform: none; -} - -nav.popup_menu ul li ul li ul li a, -nav.popup_menu ul li ul li ul li h6{ - font-size: 0.5em; - line-height: 1em; -} - -.popup_menu.medium .popup_menu_inner, -.popup_menu.medium .line, -.popup_menu.medium .line:after, .popup_menu.medium .line:before { - height: 3px; - width: 19px; -} - -.popup_menu.medium .line:before{ - top: -6px; -} - -.popup_menu.medium .line:after { - top: 6px; -} - -.popup_menu.large .popup_menu_inner, -.popup_menu.large .line, -.popup_menu.large .line:after, .popup_menu.large .line:before { - height: 4px; - width: 24px; -} - -.popup_menu.large .line:before{ - top: -8px; -} - -.popup_menu.large .line:after { - top: 8px; -} - -/* ========================================================================== - Popup menu end styles - ========================================================================== */ - -/* ========================================================================== - Pricing List Shortcode style - ========================================================================== */ -.qode_pricing_list .qode_pricing_list_holder { - list-style: none; -} - -.qode_pricing_list .qode_pricing_list_item { - position: relative; - border-bottom: 1px solid #e7e7e7; - padding: 19px 0; -} - -.qode_pricing_list .qode_pricing_item_title { - margin-bottom: 5px; - font-size: 18px; - font-weight: 600; -} - -.qode_pricing_list .qode_pricing_item_text { - padding-right: 170px; -} - -.qode_pricing_list .qode_pricing_item_price { - position: absolute; - width: 170px; - height: 100%; - text-align: right; - right: 0; - top: 0; -} - -.qode_pricing_list .qode_pricing_item_price_inner { - display: table; - height: 100%; - width: 100%; -} - -.qode_pricing_list .qode_pricing_item_price_inner span { - display: table-cell; - vertical-align: middle; - font-size: 30px; - color: #303030; - font-weight: 600; -} - -/* ========================================================================== - End of Pricing List Shortcode style - ========================================================================== */ - -/* ========================================================================== - Qode Elements Holder style - ========================================================================== */ - -.q_elements_holder{ - width: 100%; - display: table; - table-layout: fixed; -} -.q_elements_holder .q_elements_item{ - display: table-cell; - vertical-align: middle; - height: 100%; -} - -.q_elements_holder .q_elements_item_inner{ - width: 100%; -} - -.q_elements_holder.two_columns .q_elements_item { - width: 50%; -} - -.q_elements_holder.three_columns .q_elements_item { - width: 33.33333333333333%; -} - -.q_elements_holder.four_columns .q_elements_item { - width: 25%; -} - - -/* ========================================================================== - End of Qode Elements Holder style - ========================================================================== */ - - - - -/* ========================================================================== - Start of content with negative margin style - ========================================================================== */ - -.content_top_margin .content .container .container_inner.page_container_inner{ - padding: 0px; -} - -.content_top_margin .content .container .container_inner .call_to_action{ - margin: 0px -15px; -} - -.content_top_margin .content .container .container_inner .call_to_action .container_inner{ - width: 100%; -} - -/* ========================================================================== - End of content with negative margin style - ========================================================================== */ - -/* ========================================================================== - Password protected box styles - ========================================================================== */ -.post-password-form { - width: 300px; -} - -.post-password-form p { - margin-bottom: 20px; -} - -.post-password-form input[type='password'] { - width: 100%; - display: block; - margin: 5px 0 20px; - padding: 15px 12px; - border: 0; - outline: 0; - resize: none; - font-size: 13px; - line-height:17px; - background-color:#fff; - color: #818181; - font-family: inherit; - font-weight:400; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.post-password-form input[type='submit'] { - position: relative; - display: inline-block; - width: auto; - height: 39px; - line-height: 39px; - margin: 0; - padding: 0px 23px; - border: 2px solid #303030; - font-size: 13px; - font-weight: 700; - font-family: inherit; - text-align: left; - color: #303030; - text-decoration: none; - cursor: pointer; - white-space: nowrap; - outline: none; - font-style: normal; - text-transform: uppercase; - letter-spacing: 1px; - margin-bottom: 20px; - - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - background-color: transparent; - -webkit-transition: all 0.1s linear; - -moz-transition: all 0.1s linear; - -ms-transition: all 0.1s linear; - -o-transition: all 0.1s linear; - transition: all 0.1s linear; - - -webkit-box-sizing: initial !important; - -moz-box-sizing: initial !important; - box-sizing: initial !important; -} - -.post-password-form input[type='submit']:hover { - background-color: #1abc9c; - border-color: #1abc9c; - color: #fff; - text-decoration: none; -} - -/* ========================================================================== - End of password protected box styles - ========================================================================== */ - -/* ========================================================================== - Full Screen Sections Template - ========================================================================== */ - -.full_screen_holder{ - position: relative; - display: block; - z-index: 100; -} - -.full_screen_inner{ - height: 100%; - position: relative; - /* Touch detection for Windows 8 */ - -ms-touch-action: none; - /* IE 11 on Windows Phone 8.1*/ - touch-action: none; - visibility: hidden; -} - -.fp-section { - position: relative; - -webkit-box-sizing: border-box; /* Safari<=5 Android<=3 */ - -moz-box-sizing: border-box; /* <=28 */ - box-sizing: border-box; - margin: 0 !important; -} - -.fp-slide { - float: left; -} - -.fp-section.fp-table, -.fp-slide.fp-table { - display: table; - width: 100%; -} - -.fp-tableCell { - display: table-cell; - vertical-align: middle; - width: 100%; - height: 100%; -} - -.vertical_menu_enabled .full_screen_holder{ - padding-left: 260px; -} - -.boxed.vertical_menu_enabled .full_screen_holder{ - padding-left: 0; -} - -@media only screen and (max-width: 1000px){ - .vertical_menu_enabled .full_screen_holder{ - padding-left: 0; - } -} - -.full_screen_navigation_holder{ - position: absolute; - left: 0; - width: 100%; - display: block; - text-align: center; - z-index: 10000; - visibility: hidden; - -webkit-transition: opacity 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out; - -ms-transition: opacity 0.3s ease-in-out; - -o-transition: opacity 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out; -} - -.full_screen_navigation_holder.up_arrow{ - top: 30px; -} - -.full_screen_navigation_holder.down_arrow, -.full_screen_navigation_holder.side_by_side{ - position: fixed; - bottom: 30px; -} - -.full_screen_navigation_inner{ - position: relative; - display: inline-block; - vertical-align: middle; -} - -.full_screen_navigation_inner a{ - display: block; - color: #393939; - font-size: 40px; - line-height: 1em; - opacity: 1; - -webkit-transition: opacity 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out; - -ms-transition: opacity 0.3s ease-in-out; - -o-transition: opacity 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out; -} - -.full_screen_navigation_inner a:hover{ - opacity: 0.7; -} - -.full_screen_navigation_inner i{ - font-size: inherit; - color: inherit; - line-height: inherit; -} - -.full_screen_preloader{ - position: absolute; - height: 1200px; - width: 100%; - display: block; - background-color: #1c1c1c; - z-index: 10001; -} - -.full_screen_preloader .ajax_loader{ - position: absolute; - display: block; -} - -/* ========================================================================== - End of Full Screen Sections Template - ========================================================================== */ - -/* ========================================================================== - Image Gallery slider with no space - ========================================================================== */ - -.qode_image_gallery_no_space { - opacity: 0; - position: relative; -} - -.qode_image_gallery_no_space .qode_image_gallery_holder { - overflow: hidden; - position: relative; - width: 100%; -} - -.qode_image_gallery_no_space ul { - margin: 0; - overflow: hidden; - padding: 0; -} - -.qode_image_gallery_no_space ul li { - float: left; - list-style: none outside none; - margin: 0px; -} - -@media only screen and (min-width: 800px) { - .qode_image_gallery_no_space.highlight_active ul li:not(.active) { - opacity: 0.2; - } - - .qode_image_gallery_no_space.highlight_active ul li.active{ - opacity: 1 !important; - } - - .qode_image_gallery_no_space.highlight_active ul li { - -webkit-transition: opacity 0.3s ease-in-out; - -moz-transition: opacity 0.3s ease-in-out; - -ms-transition: opacity 0.3s ease-in-out; - -o-transition: opacity 0.3s ease-in-out; - transition: opacity 0.3s ease-in-out; - } -} - -@media only screen and (max-width: 800px) { - .qode_image_gallery_no_space.highlight_active ul li{ - opacity: 1 !important; - } -} - -.qode_image_gallery_no_space ul li:not(.active) a { - cursor: default; -} - -.qode_image_gallery_no_space a.prettyphoto { - display: block; - width: 100%; - height: 100%; -} - -.qode_image_gallery_no_space ul li img { - display: block; - position: relative; -} - -.qode_image_gallery_no_space .controls { - width: 100%; -} - -.qode_image_gallery_no_space .controls a.prev-slide, -.qode_image_gallery_no_space .controls a.next-slide { - vertical-align: middle; - font-size: 30px; - position: absolute; - top: 0; - height: 100%; - width: 10%; -} - -.qode_image_gallery_no_space .controls a.prev-slide span, -.qode_image_gallery_no_space .controls a.next-slide span { - margin-top: -27px; - margin-left: -27px; - position: absolute; - left: 50%; - top: 50%; - background-color: transparent; - border: 2px solid #303030; - color: #303030; - cursor: pointer; - display: block; - height: 54px; - line-height: 54px; - text-align: center; - width: 54px; - border-radius: 40px; - -webkit-transition: color .15s ease-in-out, background-color .15s ease-in-out; - -moz-transition: color .15s ease-in-out, background-color .15s ease-in-out; - -ms-transition: color .15s ease-in-out, background-color .15s ease-in-out; - -o-transition: color .15s ease-in-out, background-color .15s ease-in-out; - transition: color .15s ease-in-out, background-color .15s ease-in-out; -} - -.qode_image_gallery_no_space .controls a.prev-slide span i, -.qode_image_gallery_no_space .controls a.next-slide span i{ - vertical-align: top; -} - -.qode_image_gallery_no_space.light .controls a.prev-slide span, -.qode_image_gallery_no_space.light .controls a.next-slide span{ - color: #fff; - border-color: #fff; -} -.qode_image_gallery_no_space.dark .controls a.prev-slide span, -.qode_image_gallery_no_space.dark .controls a.next-slide span{ - color: #000; - border-color: #000; -} -.qode_image_gallery_no_space .controls a.prev-slide:hover span, -.qode_image_gallery_no_space .controls a.next-slide:hover span{ - background-color: #303030; - color: #fff; -} -.qode_image_gallery_no_space.light .controls a.prev-slide:hover span, -.qode_image_gallery_no_space.light .controls a.next-slide:hover span{ - background-color: #fff; - color: #8a8a8a; -} -.qode_image_gallery_no_space.dark .controls a.prev-slide:hover span, -.qode_image_gallery_no_space.dark .controls a.next-slide:hover span{ - background-color: #000; - color: #fff; -} -.qode_image_gallery_no_space .controls a.next-slide { - right: 20px; -} - -@media only screen and (max-width: 800px) { - .qode_image_gallery_no_space .qode_image_gallery_holder { - height: auto !important; - } - - .qode_image_gallery_no_space ul { - height: auto !important; - width: 100% !important; - } - - .qode_image_gallery_no_space ul li { - float: none; - } - - .qode_image_gallery_no_space ul li.-before, - .qode_image_gallery_no_space ul li.-after { - display: none; - } - - .qode_image_gallery_no_space ul li div { - height: auto !important; - width: 100% !important; - } - - .qode_image_gallery_no_space ul li img { - height: auto; - width: 100%; - } - - .qode_image_gallery_no_space .controls { display: none; } -} - -/* ========================================================================== - End of Image Gallery slider with no space - ========================================================================== */ - -/* ========================================================================== - Start of Countdown - ========================================================================== */ - -/* jQuery Countdown styles 2.0.0. */ - -.countdown-rtl { - direction: rtl; -} - -.countdown-row { - clear: both; - width: 100%; - padding: 0px 2px; - text-align: center; -} -.countdown-show1 .countdown-section { - width: 98%; -} -.countdown-show2 .countdown-section { - width: 48%; -} -.countdown-show3 .countdown-section { - width: 32.5%; -} -.countdown-show4 .countdown-section { - width: 24.5%; -} -.countdown-show5 .countdown-section { - width: 19.5%; -} -.countdown-show6 .countdown-section { - width: 16.25%; -} -.countdown-show7 .countdown-section { - width: 14%; -} - -.countdown{ - font-weight: 700; -} - -.countdown-section { - display: inline-block; - vertical-align: middle; - text-align: center; - font-weight: inherit; -} -.countdown-amount { - display: block; - position: relative; - font-size: 60px; - line-height: 60px; - margin-bottom: 20px; - color: inherit; -} - -/*this span.countdown_separator is added in countdown plugin in plugin.js file */ -.countdown_separator{ - display: none; - width: 30px; - height: 2px; - background-color: #818181; - margin: 30px 0px; - opacity: 0.3; -} - -.countdown.show_separator .countdown_separator{ - display: inline-block; -} - -.countdown.show_separator .countdown-amount { - margin: 0px; -} - -.countdown-period { - display: block; - font-size: 15px; - letter-spacing: 1px; - text-transform: uppercase; - color: inherit; -} -.countdown-descr { - display: block; - width: 100%; -} - -@media only screen and (max-width: 1000px){ - .countdown-amount { - font-size: 50px !important; - line-height: 50px !important; - } - - .countdown-period { - font-size: 15px !important; - } - - .countdown_separator { - width: 30px; - } -} - -@media only screen and (max-width: 600px){ - .countdown-amount { - font-size: 40px !important; - line-height: 40px !important; - margin-bottom: 15px; - } - - .countdown-period { - font-size: 12px !important; - } - - .countdown_separator { - width: 20px; - margin: 25px 0px 20px 0px; - } -} - -@media only screen and (max-width: 600px){ - .countdown-amount { - font-size: 35px !important; - line-height: 35px !important; - margin-bottom: 10px; - } - - .countdown-period { - font-size: 10px !important; - } - - .countdown_separator { - width: 15px; - margin: 20px 0px 15px 0pc; - } -} - -/* ========================================================================== - End of Countdown - ========================================================================== */ - -/* ========================================================================== - Start of Vertical Split Screen - ========================================================================== */ - -.vertical_split_slider{ - opacity: 0; - position: relative; - margin: 0px -2px; -} - -.ms-section { - position: relative; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - background-size: cover; - background-repeat: no-repeat; - padding: 0px 20px; -} - -.vertical_split_slider .ms-left .ms-section{ - background-position: 100% center !important; -} - -.vertical_split_slider .ms-right .ms-section{ - background-position: 0 center !important; -} - -.ms-section.ms-table{ - display: table; - width: 100%; -} -.ms-tableCell { - display: table-cell; - vertical-align: middle; - width: 100%; - height: 100%; - box-sizing: border-box; -} -.ms-easing { - -webkit-transition: all 0.7s ease-out; - -moz-transition: all 0.7s ease-out; - -o-transition: all 0.7s ease-out; - transition: all 0.7s ease-out; -} -#multiscroll-nav { - position: fixed; - z-index: 1000; - margin-top: -32px; - top: 50%; - opacity: 1; -} -#multiscroll-nav.right { - right: 17px; -} -#multiscroll-nav.left { - left: 17px; -} -#multiscroll-nav ul{ - margin: 0; - padding: 0; -} -#multiscroll-nav li{ - display: block; - width: 8px; - height: 8px; - margin: 13px 7px; - position: relative; -} -#multiscroll-nav li a{ - display: block; - position: relative; - z-index: 1; - width: 100%; - height: 100%; - cursor: pointer; - text-decoration: none; -} -#multiscroll-nav li .active span{ - background-color: #000; -} - -#multiscroll-nav span{ - top: 0px; - left: 0px; - width: 8px; - height: 8px; - border: 1px solid #000; - background-color: rgba(0, 0, 0, 0); - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - position: absolute; - z-index: 1; -} -.multiscroll-tooltip { - position: absolute; - color: #fff; - font-size: 14px; - font-family: arial, helvetica, sans-serif; - top: -2px; - white-space: nowrap; - max-width: 220px; -} -.multiscroll-tooltip.right { - right: 20px; -} -.multiscroll-tooltip.left { - left: 20px; -} - -.vertical_split_slider_responsive{ - display: none; -} - -@media only screen and (max-width: 1000px){ - .vertical_split_slider .ms-left { - width: 100% !important; - z-index: 2; - } - - .vertical_split_slider .ms-left .ms-section{ - background: none !important; - text-align: center !important; - } - - .vertical_split_slider .ms-right { - width: 100% !important; - z-index: 1; - } -} - -@media only screen and (max-width: 767px){ - .vertical_split_screen_initalized body.vss_responsive_adv{ - overflow-y: visible !important; - height: auto !important; - } - - .vss_responsive_adv .vertical_split_slider, - .vss_responsive_adv #multiscroll-nav { - display: none; - } - - .vertical_split_slider_responsive{ - display: block; - } - - .vss_responsive_adv .ms-section { - background-position: center center; - } -} - -/* ========================================================================== - End of Vertical Split Screen - ========================================================================== */ - -/* ========================================================================== - Start of paspartu - ========================================================================== */ - -.paspartu_outer{ - padding: 0 2% 0% 2%; - z-index: 99; /* 100 is z-index of footer, so it needs to be smaller in order to prevent minus margin on left and right paspartu */ -} - -.paspartu_outer:not(.paspartu_on_bottom_fixed){ - position: relative; -} - -body:not(.paspartu_on_top_fixed) .paspartu_outer .content:not(.has_slider) .content_inner, -.paspartu_on_top_fixed header, -.paspartu_on_top_fixed .fixed_top_header .top_header, -.paspartu_on_top_fixed .paspartu_outer .content_wrapper{ - padding-top: 2%; -} - -.paspartu_left, -.paspartu_right { - position: absolute; - height: 100%; - width: 2%; - top: 0px; - left: 0px; - background-color: #ffffff; - z-index: 101; /* one more than the Slider */ - -} - -.paspartu_outer:not(.paspartu_on_bottom_fixed):not(.disable_top_paspartu):not(disable_bottom_paspartu) .paspartu_left, -.paspartu_outer:not(.paspartu_on_bottom_fixed):not(.disable_top_paspartu):not(disable_bottom_paspartu) .paspartu_right{ - /*margin: -50% 0px; *//* because of the header types when portfolio outer is not from top of window */ - height: 200%; - margin: -5% 0; -} - -.paspartu_right{ - left: auto; - right: 0px; -} - -.paspartu_top{ - position: fixed; - padding-top: 2%; - height: 0; - width: 100%; - top:0px; - left: 0px; - background-color: #ffffff; - z-index: 200; -} - -.paspartu_bottom{ - position: relative; - padding-top: 2%; - height: 0; - width: 100%; - background-color: #ffffff; - z-index: 200; -} - -.paspartu_on_bottom_fixed .paspartu_bottom{ - position: fixed; - bottom:0px; - left: 0px; -} - -.paspartu_on_bottom_fixed footer{ - margin-bottom: 2%; -} - -body.paspartu_on_top_fixed.paspartu_on_bottom_fixed .popup_menu_holder_outer{ - padding: 2%; - box-sizing: border-box; -} - -.paspartu_enabled #multiscroll-nav.right{ - padding-right: 2%; -} - -.paspartu_outer .q_slider, -.paspartu_outer .content:not(.has_slider) .content_inner{ - background-color: #ffffff; -} - -.paspartu_outer:not(.disable_top_paspartu) .carousel-inner, -.paspartu_outer.paspartu_on_bottom_slider .carousel-inner{ - position: relative; - height: 100% !important; -} - -.paspartu_outer.disable_top_paspartu .content:not(.has_slider) .content_inner{ - padding-top: 0 !important; -} -.paspartu_outer.disable_bottom_paspartu, -.paspartu_outer.paspartu_on_bottom_fixed{ - padding-bottom: 0 !important; -} - -.paspartu_enabled .header_inner{ - position: relative; /* for search form that covers header and comes from bottom from header */ -} - -header.paspartu_header_alignment .header_bottom{ - padding: 0px 2%; -} - -header.paspartu_header_inside, -.paspartu_enabled.vertical_menu_enabled header{ - padding-left: 2%; - padding-right: 2%; - box-sizing: border-box; -} - -.paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ - margin-top: 2%; -} - -header.paspartu_header_inside.fixed_top_header .top_header, -.paspartu_enabled .vertical_split_slider_preloader, -.paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ - width: 96%; - margin-left: 2%; - margin-right: 2%; -} - -.paspartu_enabled .paspartu_outer:not(.disable_top_paspartu) .vertical_split_slider{ - margin-top: -2%; -} - -.paspartu_enabled .paspartu_outer:not(.disable_bottom_paspartu) .vertical_split_slider{ - margin-bottom: -2%; -} - -.paspartu_on_top_fixed header{ - z-index:202; -} - -.paspartu_on_top_fixed:not(.paspartu_on_bottom_fixed) .popup_menu_holder_outer{ - z-index:201; -} - -.paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, -.paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, -.paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ - margin-left: 2%; -} - -.paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right aside.vertical_menu_area, -.paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_area_background, -.paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled.vertical_menu_right .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_menu_hidden_button{ - margin-left: 0%; - margin-right: 2%; -} - -.paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, -.paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, -.paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ - margin-top: 2%; -} - -.paspartu_enabled.vertical_menu_enabled:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled.vertical_menu_width_290:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled.vertical_menu_width_290:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled.vertical_menu_width_350:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled.vertical_menu_width_350:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled.vertical_menu_width_400:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled.vertical_menu_width_400:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), -.paspartu_enabled.vertical_menu_enabled.vertical_menu_hidden .carousel-inner:not(.relative_position){ - left: 0px !important; - margin-left: 0% !important; -} - - -.vertical_menu_enabled.paspartu_on_top_fixed header{ - padding: 0px !important; -} - -/* outside paspartu - start */ - -.paspartu_enabled.vertical_menu_outside_paspartu aside.vertical_menu_area{ - z-index: 500; -} - -body.vertical_menu_outside_paspartu.paspartu_on_top_fixed .paspartu_outer{ - padding-top: 2%; -} - -body.paspartu_on_top_fixed.vertical_menu_outside_paspartu .paspartu_outer .content .content_inner{ - padding-top: 0% !important; -} - -@media only screen and (min-width: 1000px) { - - .vertical_menu_outside_paspartu .content_wrapper{ - margin-left: 2%; - padding-left: 260px; - width: 98%; - } - - .vertical_menu_outside_paspartu.vertical_menu_left.vertical_menu_width_290 .content_wrapper{ - margin-left: 2%; - padding-left: 290px; - width: 98%; - } - - .vertical_menu_outside_paspartu.vertical_menu_left.vertical_menu_width_350 .content_wrapper{ - margin-left: 2%; - padding-left: 350px; - width: 98%; - } - - .vertical_menu_outside_paspartu.vertical_menu_left.vertical_menu_width_400 .content_wrapper{ - margin-left: 2%; - padding-left: 400px; - width: 98%; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .content_wrapper{ - margin-right: 2%; - padding-right: 290px; - width: 98%; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .content_wrapper{ - margin-right: 2%; - padding-right: 350px; - width: 98%; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .content_wrapper{ - margin-right: 2%; - padding-right: 400px; - width: 98%; - } - - .vertical_menu_outside_paspartu .paspartu_middle_inner{ - padding-left: 260px; - } - - .vertical_menu_outside_paspartu .paspartu_left{ - left: 260px; - } - - .vertical_menu_outside_paspartu.vertical_menu_width_290 .paspartu_middle_inner{ - padding-left: 290px; - } - - .vertical_menu_outside_paspartu.vertical_menu_width_290 .paspartu_left{ - left: 290px; - } - - .vertical_menu_outside_paspartu.vertical_menu_width_350 .paspartu_middle_inner{ - padding-left: 350px; - } - - .vertical_menu_outside_paspartu.vertical_menu_width_350 .paspartu_left{ - left: 350px; - } - - .vertical_menu_outside_paspartu.vertical_menu_width_400 .paspartu_middle_inner{ - padding-left: 400px; - } - - .vertical_menu_outside_paspartu.vertical_menu_width_400 .paspartu_left{ - left: 400px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .paspartu_middle_inner{ - padding-left: 0px; - padding-right: 290px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .paspartu_left{ - left: 0px; - } - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .paspartu_right{ - right: 290px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .paspartu_middle_inner{ - padding-left: 0px; - padding-right: 350px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .paspartu_left{ - left: 0px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .paspartu_right{ - right: 350px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .paspartu_middle_inner{ - padding-left: 0px; - padding-right: 400px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .paspartu_left{ - left: 0px; - } - - .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .paspartu_right{ - right: 400px; - } - - body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled:not(.vertical_menu_hidden) .content .full_width{ - padding-left: 0px; - padding-right:0px; - } - - body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_290.vertical_menu_left:not(.vertical_menu_hidden) .content .full_width{ - padding-left: 0px; - padding-right:0px; - } - - body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_350.vertical_menu_left:not(.vertical_menu_hidden) .content .full_width{ - padding-left: 0px; - padding-right:0px; - } - - body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_400.vertical_menu_left:not(.vertical_menu_hidden) .content .full_width{ - padding-left: 0px; - padding-right:0px; - } - - - body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_290.vertical_menu_right:not(.vertical_menu_hidden) .content .full_width{ - padding-right:0px; - padding-left:0px; - } - - body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_350.vertical_menu_right:not(.vertical_menu_hidden) .content .full_width{ - padding-right:0px; - padding-left:0px; - } - - body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_400.vertical_menu_right:not(.vertical_menu_hidden) .content .full_width{ - padding-right:0px; - padding-left:0px; - } - -} - -.vertical_menu_outside_paspartu.vertical_menu_enabled .q_slider, -.vertical_menu_outside_paspartu.vertical_menu_enabled .full_width, -.vertical_menu_outside_paspartu.vertical_menu_enabled .content .container, -.vertical_menu_outside_paspartu.vertical_menu_enabled .title_outer, - /* .vertical_menu_outside_paspartu.vertical_menu_enabled footer, no need for footer to be excluded*/ -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .q_slider, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .full_width, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .content .container, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .title_outer, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 footer, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .q_slider, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .full_width, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .content .container, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .title_outer, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 footer, -.vertical_menu_outside_paspartu.vertical_menu_enabled .full_screen_holder, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .full_screen_holder, -.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .full_screen_holder{ - padding-left: 0px; - padding-right: 0px; -} - -.vertical_menu_outside_paspartu.vertical_menu_enabled .q_slider{ - padding-top: 0px !important; -} - -body.vertical_menu_outside_paspartu.vertical_menu_enabled:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_290:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_290.vertical_menu_right:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350.vertical_menu_right:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400.vertical_menu_right:not(.vertical_menu_hidden) .ajax_loader, -body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_right .ajax_loader{ - margin-left: 0px; -} - -/* outside paspartu - end */ - -@media only screen and (min-width: 1024px) { - header.paspartu_header_alignment .header_inner_left { - left: 2%; - } -} - -@media only screen and (max-width: 1024px) { - .paspartu_outer { - padding: 0 2% 2% 2% !important; - } - - body:not(.paspartu_on_top_fixed) .paspartu_outer .content:not(.has_slider) .content_inner, - .paspartu_top, - .paspartu_bottom, - .paspartu_on_top_fixed header, - .paspartu_on_top_fixed .fixed_top_header .top_header, - .paspartu_on_top_fixed .paspartu_outer .content_wrapper{ - padding-top: 2% !important; - } - - .paspartu_left, - .paspartu_right { - width: 2% !important; - } - - .paspartu_on_bottom_fixed footer{ - margin-bottom: 2% !important; - } - - body.paspartu_on_top_fixed.paspartu_on_bottom_fixed .popup_menu_holder_outer{ - padding: 2% !important; - } - - .paspartu_enabled #multiscroll-nav.right{ - padding-right: 2% !important; - } - - header.paspartu_header_alignment .header_bottom { - padding: 0px 2% !important; - } - - header.paspartu_header_inside, - .paspartu_enabled.vertical_menu_enabled header{ - padding-left: 2% !important; - padding-right: 2% !important; - } - - .paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ - margin-top: 2% !important; - } - - header.paspartu_header_inside.fixed_top_header .top_header, - .paspartu_enabled .vertical_split_slider_preloader, - .paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ - width: 96% !important; - margin-left: 2% !important; - margin-right: 2% !important; - } - - .paspartu_enabled .paspartu_outer:not(.disable_top_paspartu) .vertical_split_slider{ - margin-top: -2% !important; - } - - .paspartu_enabled .paspartu_outer:not(.disable_bottom_paspartu) .vertical_split_slider{ - margin-bottom: -2% !important; - } - - .paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, - .paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, - .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled .carousel-inner:not(.relative_position), - .paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ - margin-left: 2% !important; - } - - .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right aside.vertical_menu_area, - .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_area_background, - .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled.vertical_menu_right .carousel-inner:not(.relative_position), - .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_menu_hidden_button{ - margin-left: 0% !important; - margin-right: 2% !important; - } - - .paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, - .paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, - .paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ - margin-top: 2% !important; - } - - body.vertical_menu_outside_paspartu.paspartu_on_top_fixed .paspartu_outer{ - padding-top: 2% !important; - } -} - -/* ========================================================================== - End of paspartu - ========================================================================== */ - -/* ========================================================================== - Visual Composer Grid Elements -============================================================================ */ - -.vc_grid-container .vc_row.vc_grid .vc_grid-item .vc_btn { - position: relative; - display: inline-block; - width: auto; - height: 39px; - line-height: 39px; - margin: 0; - padding: 0px 23px; - border: 2px solid #303030; - font-size: 13px; - font-weight: 700; - font-family: inherit; - text-align: left; - color: #303030 !important; - text-decoration: none; - cursor: pointer; - white-space: nowrap; - outline: none; - font-style: normal; - text-transform: uppercase; - letter-spacing: 1px; - - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - background-color: transparent; - -webkit-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -moz-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -ms-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -o-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - - -webkit-box-sizing: initial !important; - -moz-box-sizing: initial !important; - box-sizing: initial !important; -} - -.vc_grid-container .vc_row.vc_grid .vc_grid-item .vc_btn:hover { - background-color: #1abc9c; - border-color: #1abc9c; - color: #fff !important; - text-decoration: none; -} - -.vc_grid-container .vc_row.vc_grid .vc_pageable-load-more-btn .vc_btn { - position: relative; - display: inline-block; - width: auto; - height: 39px; - line-height: 39px; - margin: 0; - padding: 0px 23px; - border: 2px solid #303030; - font-size: 13px; - font-weight: 700; - font-family: inherit; - text-align: left; - color: #303030 !important; - text-decoration: none; - cursor: pointer; - white-space: nowrap; - outline: none; - font-style: normal; - text-transform: uppercase; - letter-spacing: 1px; - - -o-border-radius: 4px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -ms-border-radius: 4px; - border-radius: 4px; - text-shadow: none; - - background-color: transparent; - -webkit-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -moz-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -ms-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - -o-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; - - -webkit-box-sizing: initial !important; - -moz-box-sizing: initial !important; - box-sizing: initial !important; -} - -.vc_grid-container .vc_row.vc_grid .vc_pageable-load-more-btn .vc_btn:hover { - background-color: #1abc9c; - border-color: #1abc9c; - color: #fff !important; - text-decoration: none; -} -/* -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li > a { - position: relative; - color: #303030; - display: inline-block; - width: 38px; - height: 38px; - line-height: 38px; - margin: 0 11px 0 0; - text-align:center; - color: #b4b4b4 !important; - font-size: 18px; - text-decoration: none; - text-transform: uppercase; - cursor: pointer; - white-space: nowrap; - - outline: none; - -o-border-radius: 4px !important; - -moz-border-radius: 4px !important; - -webkit-border-radius: 4px !important; - -ms-border-radius: 4px !important; - border-radius: 4px !important; - text-shadow: none; - background-color: transparent !important; - - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; -} -*/ -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-square_dots .vc_grid-owl-dot span { - border: 2px solid #e5e5e5; - background-color: transparent !important; -} - -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-square_dots .vc_grid-owl-dot span:hover { - background-color: #e3e3e3 !important; - border-color: #e3e3e3 !important; -} - -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-square_dots .vc_grid-owl-dot.active span { - background-color: #e3e3e3 !important; - border-color: #e3e3e3 !important; -} - -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-radio_dots .vc_grid-owl-dot span { - border: 2px solid #e5e5e5; - border-radius: 50%; - background-color: transparent !important; -} - -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-radio_dots .vc_grid-owl-dot span:hover { - background-color: #e3e3e3 !important; - border-color: #e3e3e3 !important; -} - -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-radio_dots .vc_grid-owl-dot.active span { - background-color: #e3e3e3 !important; - border-color: #e3e3e3 !important; -} - -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-point_dots .vc_grid-owl-dot span { - background-color: #e3e3e3 !important; -} - -.vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-fill_square_dots .vc_grid-owl-dot span { - background-color: #e3e3e3 !important; -} - -.vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-round_fill_square_dots .vc_grid-owl-dot span { - background-color: #e3e3e3 !important; -} - -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li > a { - background-color: transparent !important; - color: #b4b4b4 !important; - -o-border-radius: 4px !important; - -moz-border-radius: 4px !important; - -webkit-border-radius: 4px !important; - -ms-border-radius: 4px !important; - border-radius: 4px !important; - font-size: 18px; - margin: 0 11px 0 0; - text-align:center; - width: 42px; - height: 42px; - text-decoration: none; - text-transform: uppercase; - cursor: pointer; - white-space: nowrap; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - border: 2px solid #e5e5e5; -} - -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li > a:hover { - color: #303030 !important; - background-color: #e3e3e3 !important; - border-color: #e3e3e3; -} -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li.vc_grid-active > a { - color: #303030 !important; - background-color: #e3e3e3 !important; - border-color: #e3e3e3; -} - -.vc_grid-container .vc_grid-pagination-list.vc_grid-pagination_rounded_light > li > a, -.vc_grid-container .vc_grid-pagination-list.vc_grid-pagination_rounded_dark > li > a, -.vc_grid-container .vc_grid-pagination-list.vc_grid-pagination_rounded > li > a { - border-radius: 30px !important; -} - -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_square > li > a, -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_square_light > li > a, -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_square_dark > li > a { - line-height: 38px; - border-radius: 0 !important; -} - -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_stripes_dark > li > a, -.vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_stripes_light > li > a { - width: 22px; - height: 36px; - line-height: 36px; -} - -.vc_grid.vc_row.vc_grid-gutter-30px { - margin-bottom: 0 !important; -} - -.vc_grid-container .vc_grid-filter.vc_grid-filter-color-grey > .vc_grid-filter-item { - border: none !important; -} - -.vc_grid-container .vc_grid-filter.vc_grid-filter-color-grey > .vc_grid-filter-item:hover, -.vc_grid-container .vc_grid-filter.vc_grid-filter-color-grey > .vc_grid-filter-item.vc_active { - background: transparent; -} - -/* ========================================================================== - End of Visual Composer Grid Elements -============================================================================ */ - -/* ========================================================================== - Start of overlapping content - ========================================================================== */ - -.overlapping_content .title_outer{ - position: relative; - z-index: 50; /* smaller than the content, so content could be over title */ -} - -.overlapping_content .content > .container{ - background-color: #f8f8f8; -} - -.overlapping_content .content .content_inner > .container > .overlapping_content, -.overlapping_content .content .content_inner > .full_width > .full_width_inner{ - margin-top: -40px; - position: relative; - z-index: 100; /* greater than the title, so content could be over title */ -} - -.overlapping_content .title .title_holder .container{ - padding-bottom: 40px; - box-sizing: border-box; -} - -.overlapping_content .content .content_inner > .container{ - text-align: center; -} - -.overlapping_content .content .content_inner > .container > .overlapping_content{ - display: inline-block; - vertical-align: middle; - margin-right: auto; - margin-left: auto; - padding: 0px 40px; - background-color: #ffffff; -} - -.transparent_content.overlapping_content .content .content_inner > .container, -.transparent_content.overlapping_content .content .content_inner > .full_width > .full_width_inner{ /* full_width_inner because of the negative margin on it */ - background-color: #ffffff; -} - -.overlapping_content .content .content_inner > .container > .overlapping_content .overlapping_content_inner{ - overflow: hidden; - text-align: left; -} - -.overlapping_content_margin{ - margin: 0px -40px; - display: block; - position: relative; -} - -@media only screen and (max-width: 1200px) { - .overlapping_content .content .content_inner > .container > .overlapping_content{ - padding: 0px 20px !important; - } - .overlapping_content_margin { - margin: 0px -20px !important; - } -} - -@media only screen and (max-width: 1000px) { - header .overlapping_content_margin { - margin: 0px !important; - } -} - -/* ========================================================================== - End of overlapping content - ========================================================================== */ - -/* ========================================================================== - Start blog with next post on bottom - ========================================================================== */ - -.blog_vertical_loop .full_width_inner{ - margin: 0px !important; -} - -.blog_vertical_loop article{ - position: relative; - vertical-align: middle; - z-index: 1; /*one after another overlapping*/ - margin: 0px 0px 140px 0px; -} - -.blog_vertical_loop article.move_up{ - -webkit-transition: transform 450ms ease 0s; - transition: transform 450ms ease 0s; -} - -.blog_vertical_loop article.fade_out { - opacity: 0; - transform: scale(0.8) translate3d(0px, -10%, 0px); - transition: all 450ms ease 0s; -} - -.blog_vertical_loop article .post_image{ - margin-bottom: 55px !important; - height: 400px; -} - -.blog_vertical_loop article .post_image_inner{ - height: 100%; - overflow: hidden; -} - -.blog_vertical_loop article .post_image_inner a{ - position: absolute; - width: 100%; - height: 100%; - top: 0px; - left: 0px; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; -} - -.blog_vertical_loop article.previous_post{ - position: absolute; - opacity: 0; - transform: scale(0.8) translate3d(0px, -10%, 0px); -} - -.blog_vertical_loop article.fade_in { - transition: all 450ms ease 0s; - opacity: 1; - transform: scale(1) translate3d(0px, 0px, 0px); -} - -.blog_vertical_loop article.next_post, -.blog_vertical_loop article.next_post .post_content_holder .post_image{ - margin: 0px !important; -} - -.blog_vertical_loop article.next_post .post_content_holder > .grid_section, -.blog_vertical_loop article.next_post .post_content_holder .post_image > .grid_section{ - display: none; -} - -.blog_vertical_loop .blog_load_next{ - display: none; - position: absolute; - left: 0; - top: -30px; - width: 100%; -} - -.blog_vertical_loop article.next_post .blog_load_next{ - display: block; -} - -.blog_vertical_loop .blog_load_prev{ - display: block; - position: absolute; - left: 0; - bottom: -30px; - width: 100%; -} - -.blog_vertical_loop article.next_post .blog_load_prev{ - display: none; -} - -.blog_vertical_loop_button{ - text-align: left; -} - -.blog_vertical_loop_back_button{ - text-align: right; -} - -.blog_vertical_loop_button .button_icon a, -.blog_vertical_loop_back_button .button_icon a{ - width: 60px; - height: 60px; - background-color: #303030; - display: inline-block; - position: relative; - text-align: center; - border-radius: 50%; - -webkit-transition: background-color 0.15s ease-out; - -moz-transition: background-color 0.15s ease-out; - -ms-transition: background-color 0.15s ease-out; - -o-transition: background-color 0.15s ease-out; - transition: background-color 0.15s ease-out; -} - -.blog_vertical_loop_button .button_icon a:before, -.blog_vertical_loop_back_button .button_icon a:before{ - content: '3'; - font-family: "ElegantIcons"; - font-variant: normal; - font-weight: normal; - line-height: 60px; - text-transform: none; - color: #ffffff; - font-size: 22px; - -webkit-transition: color 0.15s ease-out; - -moz-transition: color 0.15s ease-out; - -ms-transition: color 0.15s ease-out; - -o-transition: color 0.15s ease-out; - transition: color 0.15s ease-out; -} - -.blog_vertical_loop_back_button .button_icon a:before{ - content: 'J'; -} - -.blog_vertical_loop_button_holder .last_page{ - display: none; -} - -.blog_vertical_loop article .post_image_title{ - opacity: 0; - position: absolute; - top: 0px; - left: 0px; - width: 100%; - height: 100%; - z-index: 10; - display: table; - -webkit-transition: all 0.5s ease 0s ; - transition: all 0.5s ease 0s; -} - -.blog_vertical_loop article.next_post .post_image_title{ - opacity: 1; -} - -.blog_vertical_loop article .post_image_title .post_image_title_inner{ - display: table-cell; - vertical-align: middle; - text-align: center; - background-color: rgba(0,0,0,0.6); -} - -.blog_vertical_loop article .post_image_title .post_image_title_inner h2{ - color: #ffffff; -} - -.blog_holder.blog_vertical_loop_type{ - position: relative; -} - -.blog_holder.blog_vertical_loop_type article:not(.format-quote):not(.format-link) .social_share_list_holder{ - margin-top: 15px; -} - -.blog_holder.blog_vertical_loop_type .qbutton.loop_more{ - margin: 40px 0px 0px 0px; -} -.blog_holder.blog_vertical_loop_type article:not(.format-quote):not(.format-link) .post_text .post_text_inner{ - background-color: transparent; - padding: 0; -} -.blog_holder.blog_vertical_loop_type article.format-quote .post_text, -.blog_holder.blog_vertical_loop_type article.format-link .post_text{ - margin-bottom: 30px; -} -.blog_holder.blog_vertical_loop_type article .post_text h2{ - margin-bottom: 35px; -} - -.blog_holder article.blog_vertical_loop_type .post_info{ - margin-bottom:8px; -} - -.blog_holder.blog_vertical_loop_type article .post_info > span, -.blog_holder.blog_vertical_loop_type article .post_info > div { - padding-right: 20px; - position: relative; - float: left; -} -.blog_holder.blog_vertical_loop_type article .post_info > span:last-child, -.blog_holder.blog_vertical_loop_type article .post_info > div:last-child{ - padding-right: 0px; -} - -.blog_holder.blog_vertical_loop_type article .post_info > span:after, -.blog_holder.blog_vertical_loop_type article .post_info > div:after { - position: absolute; - right: 5px; - top: 0; - content: "/"; -} - -.blog_holder.blog_vertical_loop_type article .post_info > span:last-child:after, -.blog_holder.blog_vertical_loop_type article .post_info > div:last-child:after { - content: ""; -} - -.blog_holder.blog_vertical_loop_type .blog_like a { - line-height: inherit; -} -/* ========================================================================== - End blog with next post on bottom - ========================================================================== */ - -/* ========================================================================== - Start of Parallax Layers -============================================================================ */ - -.qode_parallax_layers{ - width: 100%; - height: 500px; - position: relative; - overflow: hidden; -} - -.qode_parallax_layers_holder{ - position: relative; - width: 110%; - height: 110%; - top: -5%; - left: -5%; -} - -.qode_parallax_layers_holder .image{ - position: absolute; - top: 0px; - left: 0px; - width: 100%; - height: 100%; - background-size: cover; - background-position: center center; - transform: translateZ(0px); - -webkit-transform: translateZ(0px); -} - -.qode_parallax_layers_holder .paralax_layers_content_holder{ - position: absolute; - top: 0px; - left: 0px; - width: 100%; - height: 100%; -} - -.qode_parallax_layers_holder .paralax_layers_content{ - display: table; - width: 100%; - height: 100%; -} - -.qode_parallax_layers_holder .paralax_layers_content_inner{ - display: table-cell; - vertical-align: middle; - width: 100%; - height: 100%; - text-align: center; -} - -/* ========================================================================== - End of Parallax Layers -============================================================================ */ - diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java index f1a150ac0..b8e86fb86 100644 --- a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java @@ -74,6 +74,7 @@ public class ClientRoSessionDataReplicatedImpl extends AppSessionDataReplicatedI private static final String REQUEST_TYPE = "REQUEST_TYPE"; private static final String STATE = "STATE"; private static final String TXTIMER_ID = "TXTIMER_ID"; + private static final String RETRANSMISSION_TIMER_ID = "RETRANSMISSION_TIMER_ID"; private static final String TXTIMER_REQUEST = "TXTIMER_REQUEST"; private static final String BUFFER = "BUFFER"; private static final String GRA = "GRA"; @@ -187,6 +188,24 @@ public void setTxTimerId(Serializable txTimerId) { } } + public Serializable getRetransmissionTimerId() { + if (exists()) { + return (Serializable) getNode().get(RETRANSMISSION_TIMER_ID); + } + else { + throw new IllegalStateException(); + } + } + + public void setRetransmissionTimerId(Serializable txTimerId) { + if (exists()) { + getNode().put(RETRANSMISSION_TIMER_ID, txTimerId); + } + else { + throw new IllegalStateException(); + } + } + @Override public Request getTxTimerRequest() { if (exists()) { diff --git a/core/jdiameter/api/.gitignore b/core/jdiameter/api/.gitignore new file mode 100644 index 000000000..5de4ab8be --- /dev/null +++ b/core/jdiameter/api/.gitignore @@ -0,0 +1,11 @@ +/target +/target +/target +/target +/target +/target +/target +/target +/target +/target +/target diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/Configuration.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/Configuration.java index 14c99d5de..d0311bd66 100644 --- a/core/jdiameter/api/src/main/java/org/jdiameter/api/Configuration.java +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/Configuration.java @@ -105,6 +105,16 @@ public interface Configuration { */ byte[] getByteArrayValue(int key, byte[] defaultValue); + /** + * Returns the int[] point value of the given key. + * + * @param key the key + * @param defaultValue the Default Value + * @return the value, or defaultValue if the key was not found or was found + * but was not a int[] point number + */ + int[] getIntArrayValue(int key, int[] defaultValue); + /** * Returns the boolean point value of the given key. * diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/MutableConfiguration.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/MutableConfiguration.java index 0a41f0419..966c8b678 100644 --- a/core/jdiameter/api/src/main/java/org/jdiameter/api/MutableConfiguration.java +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/MutableConfiguration.java @@ -86,6 +86,13 @@ public interface MutableConfiguration extends Configuration { */ void setByteArrayValue(int key, byte[] value); + /** + * Set int array value to configuration + * @param key key of value + * @param value int array value + */ + void setIntArrayValue(int key, int[] value); + /** * Set boolean value to configuration * @param key key of value diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java new file mode 100644 index 000000000..40f999a79 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java @@ -0,0 +1,101 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2006, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jdiameter.api; + +/** + * Signals that no peer is available for routing. + */ +public class NoMorePeersAvailableException extends RouteException { + + private static final long serialVersionUID = 1L; + + private boolean sessionPersistentRoutingEnabled = false; + private int lastSelectedPeerRating = -1; + private String roundRobinContextDescription = null; + + /** + * Constructor with reason string and routing details + * @param message reason string + */ + public NoMorePeersAvailableException(String message, boolean spre, String rrcd, int lspr) { + super(message); + this.setSessionPersistentRoutingEnabled(spre); + this.setRoundRobinContextDescription(rrcd); + this.setLastSelectedPeerRating(lspr); + } + + /** + * Constructor with reason string and parent exception + * @param message message reason string + * @param cause parent exception + */ + public NoMorePeersAvailableException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor with reason string + * @param message reason string + */ + public NoMorePeersAvailableException(String message) { + super(message); + } + + public boolean isSessionPersistentRoutingEnabled() { + return sessionPersistentRoutingEnabled; + } + + public void setSessionPersistentRoutingEnabled(boolean sessionPersistentRoutingEnabled) { + this.sessionPersistentRoutingEnabled = sessionPersistentRoutingEnabled; + } + + public String getRoundRobinContextDescription() { + return roundRobinContextDescription; + } + + public void setRoundRobinContextDescription(String roundRobinContextDescription) { + this.roundRobinContextDescription = roundRobinContextDescription; + } + + public int getLastSelectedPeerRating() { + return lastSelectedPeerRating; + } + + public void setLastSelectedPeerRating(int lastSelectedPeerRating) { + this.lastSelectedPeerRating = lastSelectedPeerRating; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder + .append("NoMorePeersAvailableException [sessionPersistentRoutingEnabled=") + .append(sessionPersistentRoutingEnabled) + .append(", lastSelectedPeerRating=").append(lastSelectedPeerRating) + .append(", roundRobinContextDescription=") + .append(roundRobinContextDescription) + .append(", message=").append(getMessage()) + .append("]"); + return builder.toString(); + } +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/RequestType.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/RequestType.java new file mode 100644 index 000000000..29dfb45ce --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/RequestType.java @@ -0,0 +1,59 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2006, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jdiameter.api; + +/** + * This enumerated class defines CC-Request-Type AVP possible values as described in RFC 4006: + * + *
      + *     The CC-Request-Type AVP (AVP Code 416) is of type Enumerated and
      + *     contains the reason for sending the credit-control request message.
      + *     It MUST be present in all Credit-Control-Request messages.  The
      + *     following values are defined for the CC-Request-Type AVP:
      + *
      + *     INITIAL_REQUEST                 1
      + *     UPDATE_REQUEST                  2
      + *     TERMINATION_REQUEST             3
      + *     EVENT_REQUEST                   4
      + * 
      + */ +public enum RequestType { + INITIAL_REQUEST(1), + UPDATE_REQUEST(2), + TERMINATION_REQUEST(3), + EVENT_REQUEST(4); + + private final int value; + + RequestType(int value) { + this.value = value; + } + + /** + * Gets value of the corresponding constant as defined in RFC + * @return value of the AVP + */ + public int value() { + return this.value; + } +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/SessionPersistenceStorage.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/SessionPersistenceStorage.java new file mode 100644 index 000000000..f9e21be24 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/SessionPersistenceStorage.java @@ -0,0 +1,41 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2010, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jdiameter.api; + +import java.util.List; + +/** + * Enables to review and supervise the current state of session persistence map that is used + * for routing that preserves sticky sessions paradigm. Read only access is given for + * the sake of safety issues. + */ +public interface SessionPersistenceStorage { + + /** + * Returns a list of all session persistence records that are currently in operation. + * + * @param maxLimit maximum number of records to be listed (0 corresponds to no limit) + * @return list of active records + */ + List dumpStickySessions(int maxLimit); +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/Stack.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/Stack.java index c6d28ea88..6e5723118 100644 --- a/core/jdiameter/api/src/main/java/org/jdiameter/api/Stack.java +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/Stack.java @@ -134,6 +134,13 @@ public interface Stack extends Wrapper { */ SessionFactory getSessionFactory() throws IllegalDiameterStateException; + /** + * Return SessionPersistenceStorage instance + * @return SessionPersistenceStorage instance + * @throws IllegalDiameterStateException if stack is not configured + */ + SessionPersistenceStorage getSessionPersistenceStorage(); + /** * Return Dictionary instance * @return Dictionary instance diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java index 59954f0a3..9eae0683c 100644 --- a/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java @@ -44,7 +44,9 @@ import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; +import org.jdiameter.api.Message; import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Peer; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; @@ -103,6 +105,35 @@ void doReAuthRequest(ClientRoSession session, ReAuthRequest request) void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + /** + * Notifies this ClientRoSessionListener that message delivery timeout expired and there was no response from + * any of remote peers in spite of numerous retransmissions and performing failover algorithm. + * + * @param session parent application session (FSM) + * @param msg request object + * @throws InternalException The InternalException signals that internal error has occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void doRequestTimeout(ClientRoSession session, Message msg, Peer peer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + /** + * Notifies this ClientRoSessionListener that message cannot be delivered due to lack of remote peers being available at the moment. + * + * @param cause root cause containing detailed description + * @param session parent application session (FSM) + * @param msg request object + * @param peer last remote peer that has been selected for routing + * @throws InternalException The InternalException signals that internal error has occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void doPeerUnavailability(RouteException cause, ClientRoSession session, Message msg, Peer peer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + /** * Provides with default value of DDFH AVP - this is used when AVP is not present or send * operation fails for some reason.
      diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IContainer.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IContainer.java index 4f881ee13..588ceef8a 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IContainer.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IContainer.java @@ -42,16 +42,17 @@ package org.jdiameter.client.api; -import java.io.IOException; -import java.util.concurrent.ScheduledExecutorService; + import org.jdiameter.api.AvpDataException; + import org.jdiameter.api.Configuration; + import org.jdiameter.api.IllegalDiameterStateException; + import org.jdiameter.api.NetworkReqListener; + import org.jdiameter.api.NoMorePeersAvailableException; + import org.jdiameter.api.RouteException; + import org.jdiameter.api.Stack; + import org.jdiameter.common.api.concurrent.IConcurrentFactory; -import org.jdiameter.api.AvpDataException; -import org.jdiameter.api.Configuration; -import org.jdiameter.api.IllegalDiameterStateException; -import org.jdiameter.api.NetworkReqListener; -import org.jdiameter.api.RouteException; -import org.jdiameter.api.Stack; -import org.jdiameter.common.api.concurrent.IConcurrentFactory; + import java.io.IOException; + import java.util.concurrent.ScheduledExecutorService; /** * This interface extends behavior of stack interface @@ -102,7 +103,7 @@ public interface IContainer extends Stack { * @throws IllegalDiameterStateException * @throws IOException */ - void sendMessage(IMessage session) throws RouteException, AvpDataException, IllegalDiameterStateException, IOException; + void sendMessage(IMessage session) throws RouteException, NoMorePeersAvailableException, AvpDataException, IllegalDiameterStateException, IOException; /** diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java index ecdb94c7a..907d111b3 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java @@ -42,12 +42,12 @@ package org.jdiameter.client.api; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - import org.jdiameter.api.ApplicationId; import org.jdiameter.client.api.controller.IPeer; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + /** * This interface extends basic message interface * Data: $Date: 2009/07/27 18:05:03 $ @@ -170,6 +170,37 @@ public interface IMessage extends IRequest, IAnswer { */ boolean isTimeOut(); + /** + * Tells if there are any timers set to monitor potential retransmissions + * @return true if potential retransmissions will be handled + */ + boolean isRetransmissionSupervised(); + + /** + * Marks that message to be under supervision timers guarding retransmissions + * @param arg true if supervision is active + */ + void setRetransmissionSupervised(boolean arg); + + /** + * Tells if the number of allowed retransmissions for this message is + * already exceeded or not. + * @return false if no more retransmissions are allowed + */ + boolean isRetransmissionAllowed(); + + /** + * Sets the number of allowed retransmissions for this message that can be performed + * in case of failure detection. + * @param arg number of allowed retransmissions + */ + void setNumberOfRetransAllowed(int arg); + + /** + * Decrements the number of allowed retransmissions for this message. + */ + void decrementNumberOfRetransAllowed(); + /** * Set event listener * @param listener event listener diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IPeerTable.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IPeerTable.java index c4998c36a..f4e2cb52a 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IPeerTable.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IPeerTable.java @@ -42,16 +42,17 @@ package org.jdiameter.client.api.controller; -import java.io.IOException; -import java.util.Map; + import org.jdiameter.api.AvpDataException; + import org.jdiameter.api.IllegalDiameterStateException; + import org.jdiameter.api.NetworkReqListener; + import org.jdiameter.api.NoMorePeersAvailableException; + import org.jdiameter.api.PeerTable; + import org.jdiameter.api.RouteException; + import org.jdiameter.client.api.IAssembler; + import org.jdiameter.client.api.IMessage; -import org.jdiameter.api.AvpDataException; -import org.jdiameter.api.IllegalDiameterStateException; -import org.jdiameter.api.NetworkReqListener; -import org.jdiameter.api.PeerTable; -import org.jdiameter.api.RouteException; -import org.jdiameter.client.api.IAssembler; -import org.jdiameter.client.api.IMessage; + import java.io.IOException; + import java.util.Map; /** * This interface provide additional methods for PeerTable interface @@ -94,7 +95,7 @@ public interface IPeerTable extends PeerTable { * @throws RouteException * @throws AvpDataException */ - void sendMessage(IMessage message) throws IllegalDiameterStateException, IOException, RouteException, AvpDataException; + void sendMessage(IMessage message) throws IllegalDiameterStateException, IOException, RouteException, NoMorePeersAvailableException, AvpDataException; /** * Register session lister diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/router/IRouter.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/router/IRouter.java index f298346d1..2772d2c17 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/router/IRouter.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/router/IRouter.java @@ -45,6 +45,7 @@ import org.jdiameter.api.AvpDataException; import org.jdiameter.api.InternalException; import org.jdiameter.api.RouteException; +import org.jdiameter.api.Wrapper; import org.jdiameter.client.api.IAnswer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; @@ -53,13 +54,13 @@ import org.jdiameter.client.api.controller.IRealmTable; /** - * This class describe Router functionality + * This class describes Router functionality * * @author erick.svenson@yahoo.com * @author
      Alexandre Mendonca * @author Bartosz Baranowski */ -public interface IRouter { +public interface IRouter extends Wrapper { /** * Return peer from inner peer table by predefined parameters. Fetches peer based on message content, that is HBH or realm/host avp contents. @@ -130,4 +131,9 @@ public interface IRouter { */ boolean updateRoute(IRequest message) throws RouteException, AvpDataException; + /** + * Tells whether session persistence is preserved while making routing decisions among peers. + * @return true if sticky sessions are applied + */ + boolean isSessionAware(); } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/StackImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/StackImpl.java index 82712402d..c19f5e87b 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/StackImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/StackImpl.java @@ -42,20 +42,6 @@ package org.jdiameter.client.impl; -import static org.jdiameter.client.impl.helpers.ExtensionPoint.ControllerLayer; -import static org.jdiameter.client.impl.helpers.ExtensionPoint.StackLayer; -import static org.jdiameter.client.impl.helpers.ExtensionPoint.TransportLayer; -import static org.jdiameter.client.impl.helpers.Parameters.Assembler; -import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.ProcessingMessageTimer; - -import java.io.IOException; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - import org.jdiameter.api.AvpDataException; import org.jdiameter.api.BaseSession; import org.jdiameter.api.Configuration; @@ -70,6 +56,7 @@ import org.jdiameter.api.PeerTable; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; +import org.jdiameter.api.SessionPersistenceStorage; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.api.validation.ValidatorLevel; @@ -88,6 +75,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import static org.jdiameter.client.impl.helpers.ExtensionPoint.ControllerLayer; +import static org.jdiameter.client.impl.helpers.ExtensionPoint.StackLayer; +import static org.jdiameter.client.impl.helpers.ExtensionPoint.TransportLayer; +import static org.jdiameter.client.impl.helpers.Parameters.Assembler; +import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.ProcessingMessageTimer; + /** * Use stack extension point * @@ -404,6 +405,15 @@ public MetaData getMetaData() { return assembler.getComponentInstance(IMetaData.class); } + @Override + public SessionPersistenceStorage getSessionPersistenceStorage() { + if (state == StackState.IDLE) { + throw new IllegalStateException("Session storage not defined"); + } + ISessionDatasource sds = assembler.getComponentInstance(ISessionDatasource.class); + return sds instanceof SessionPersistenceStorage ? (SessionPersistenceStorage) sds : null; + } + @Override @SuppressWarnings("unchecked") public T getSession(String sessionId, Class clazz) throws InternalException { diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/ClientCCASessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/ClientCCASessionImpl.java index 955f0eeba..3b1e6093c 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/ClientCCASessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/ClientCCASessionImpl.java @@ -1,55 +1,47 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, TeleStax Inc. and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.client.impl.app.cca; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - import org.jdiameter.api.Answer; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.EventListener; @@ -77,6 +69,7 @@ import org.jdiameter.common.api.app.cca.ClientCCASessionState; import org.jdiameter.common.api.app.cca.ICCAMessageFactory; import org.jdiameter.common.api.app.cca.IClientCCASessionContext; +import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; @@ -84,6 +77,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + /** * Client Credit-Control Application session implementation * @@ -112,7 +113,7 @@ public class ClientCCASessionImpl extends AppCCASessionImpl implements ClientCCA protected static final long TX_TIMER_DEFAULT_VALUE = 30 * 60 * 1000; // miliseconds - protected long[] authAppIds = new long[] { 4 }; + protected long[] authAppIds = new long[]{4}; protected static final int CCFH_TERMINATE = 0; protected static final int CCFH_CONTINUE = 1; @@ -121,11 +122,13 @@ public class ClientCCASessionImpl extends AppCCASessionImpl implements ClientCCA private static final int DDFH_TERMINATE_OR_BUFFER = 0; private static final int DDFH_CONTINUE = 1; - // CC-Request-Type Values --------------------------------------------------- + // Requested-Action Values -------------------------------------------------- private static final int DIRECT_DEBITING = 0; private static final int REFUND_ACCOUNT = 1; private static final int CHECK_BALANCE = 2; private static final int PRICE_ENQUIRY = 3; + + // CC-Request-Type --------------------------------------------------------- private static final int EVENT_REQUEST = 4; // Error Codes -------------------------------------------------------------- @@ -147,9 +150,9 @@ public class ClientCCASessionImpl extends AppCCASessionImpl implements ClientCCA temporaryErrorCodes = Collections.unmodifiableSet(tmp); } - public ClientCCASessionImpl(IClientCCASessionData data, ICCAMessageFactory fct, ISessionFactory sf, ClientCCASessionListener lst, - IClientCCASessionContext ctx, StateChangeListener stLst) { - super(sf, data); + public ClientCCASessionImpl(IClientCCASessionData data, ICCAMessageFactory fct, ISessionDatasource sds, ISessionFactory sf, ClientCCASessionListener lst, + IClientCCASessionContext ctx, StateChangeListener stLst) { + super(sds, sf, data); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } @@ -180,7 +183,7 @@ protected int getLocalDDFH() { @Override public void sendCreditControlRequest(JCreditControlRequest request) - throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { extractFHAVPs(request, null); this.handleEvent(new Event(true, request, null)); } @@ -229,8 +232,7 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce setState(ClientCCASessionState.PENDING_EVENT); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table logger.debug("Failure handling send event request", e); handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); @@ -260,8 +262,7 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce } deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); - } - catch (AvpDataException e) { + } catch (AvpDataException e) { logger.debug("Failure handling received answer event", e); setState(ClientCCASessionState.IDLE, false); } @@ -299,11 +300,9 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce dispatch(); return true; - } - catch (Exception e) { + } catch (Exception e) { throw new InternalException(e); - } - finally { + } finally { sendAndStateLock.unlock(); } } @@ -327,8 +326,7 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx setState(ClientCCASessionState.PENDING_INITIAL); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } @@ -351,8 +349,13 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx // New State: OPEN stopTx(); setState(ClientCCASessionState.OPEN); - } - else if (isProvisional(resultCode) || isFailure(resultCode)) { + //Session persistence record shall be created after a peer had answered the + //first (initial) request for that session + if (isSessionPersistenceEnabled()) { + initSessionPersistenceContext(localEvent.getRequest(), localEvent.getAnswer()); + startSessionInactivityTimer(); + } + } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((JCreditControlAnswer) answer, (JCreditControlRequest) localEvent.getRequest(), eventType); } deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); @@ -402,11 +405,13 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // Action: Send RAA followed by CC update request, start Tx // New State: PENDING_U startTx((JCreditControlRequest) localEvent.getRequest()); + if (isSessionPersistenceEnabled()) { + startSessionInactivityTimer(); + } setState(ClientCCASessionState.PENDING_UPDATE); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } @@ -426,11 +431,13 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // Event: User service terminated // Action: Send CC termination request // New State: PENDING_T + if (isSessionPersistenceEnabled()) { + stopSessionInactivityTimer(); + } setState(ClientCCASessionState.PENDING_TERMINATION); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -440,8 +447,7 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { case SEND_RAA: try { dispatchEvent(localEvent.getAnswer()); - } - catch (Exception e) { + } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -464,8 +470,7 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // New State: OPEN stopTx(); setState(ClientCCASessionState.OPEN); - } - else if (isProvisional(resultCode) || isFailure(resultCode)) { + } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((JCreditControlAnswer) answer, (JCreditControlRequest) localEvent.getRequest(), eventType); } deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); @@ -497,8 +502,7 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // New State: PENDING_U try { dispatchEvent(localEvent.getAnswer()); - } - catch (Exception e) { + } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -516,8 +520,7 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // New State: PENDING_T dispatchEvent(localEvent.getRequest()); // No transition - } - catch (Exception e) { + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table // handleSendFailure(e, eventType); } @@ -551,11 +554,9 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { dispatch(); return true; - } - catch (Exception e) { + } catch (Exception e) { throw new InternalException(e); - } - finally { + } finally { sendAndStateLock.unlock(); } } @@ -584,8 +585,7 @@ public void timeoutExpired(Request request) { if (request.getCommandCode() == JCreditControlAnswer.code) { try { handleSendFailure(null, null, request); - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure processing timeout message for request", e); } } @@ -602,8 +602,7 @@ protected void startTx(JCreditControlRequest request) { //this.txFuture = scheduler.schedule(new TxTimerTask(this, request), txTimerValue, TimeUnit.SECONDS); try { this.sessionData.setTxTimerRequest((Request) ((AppEventImpl) request).getMessage()); - } - catch (Exception e) { + } catch (Exception e) { throw new IllegalArgumentException("Failed to store request.", e); } this.sessionData.setTxTimerId(this.timerFacility.schedule(this.getSessionId(), TX_TIMER_NAME, TX_TIMER_DEFAULT_VALUE)); @@ -625,6 +624,15 @@ protected void stopTx() { public void onTimer(String timerName) { if (timerName.equals(TX_TIMER_NAME)) { new TxTimerTask(this, this.sessionData.getTxTimerRequest()).run(); + } else { + try { + sendAndStateLock.lock(); + super.onTimer(timerName); + } catch (Exception ex) { + logger.error("Cannot properly handle timer expiry", ex); + } finally { + sendAndStateLock.unlock(); + } } } @@ -639,7 +647,7 @@ protected void setState(ClientCCASessionState newState, boolean release) { this.sessionData.setClientCCASessionState(newState); for (StateChangeListener i : stateListeners) { - i.stateChanged(this,(Enum) oldState, (Enum) newState); + i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ClientCCASessionState.IDLE) { @@ -647,9 +655,16 @@ protected void setState(ClientCCASessionState newState, boolean release) { this.release(); } stopTx(); + + if (isSessionPersistenceEnabled()) { + stopSessionInactivityTimer(); + if (!release) { + String oldPeer = flushSessionPersistenceContext(); + logger.debug("Session state reset, routing context for peer [{}] was removed from session [{}]", oldPeer, this.getSessionId()); + } + } } - } - catch (Exception e) { + } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure switching to state " + this.sessionData.getClientCCASessionState() + " (release=" + release + ")", e); } @@ -662,15 +677,12 @@ public void release() { try { this.sendAndStateLock.lock(); super.release(); - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failed to release session", e); - } - finally { + } finally { sendAndStateLock.unlock(); } - } - else { + } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } @@ -692,8 +704,7 @@ protected void handleSendFailure(Exception e, Event.Type eventType, Message requ // New State: IDLE setState(ClientCCASessionState.IDLE); context.indicateServiceError(this); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { switch (getLocalDDFH()) { case DDFH_TERMINATE_OR_BUFFER: // Current State: PENDING_E @@ -715,8 +726,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { default: logger.warn("Invalid Direct-Debiting-Failure-Handling AVP value {}", getLocalDDFH()); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag @@ -724,8 +734,7 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { setState(ClientCCASessionState.IDLE, false); request.setReTransmitted(true); this.sessionData.setBuffer((Request) request); - } - else { + } else { logger.warn("Invalid Requested-Action AVP value {}", gatheredRequestedAction); } break; @@ -775,8 +784,7 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { } } dispatch(); - } - finally { + } finally { this.sendAndStateLock.unlock(); } } @@ -800,16 +808,14 @@ protected void handleFailureMessage(JCreditControlAnswer answer, JCreditControlR context.denyAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { + } else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { // Current State: PENDING_E // Event: Failed answer or answer received w/ result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx expired // Action: - // New State: IDLE setState(ClientCCASessionState.IDLE); } - } - else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { + } else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { // Current State: PENDING_E // Event: CC event answer received with result code CREDIT_CONTROL_NOT_APPLICABLE; requested action DIRECT_DEBITING // Action: Grant service to end user @@ -817,8 +823,7 @@ else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction context.grantAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); - } - else if (temporaryErrorCodes.contains(resultCode)) { + } else if (temporaryErrorCodes.contains(resultCode)) { if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY @@ -827,8 +832,7 @@ else if (temporaryErrorCodes.contains(resultCode)) { context.indicateServiceError(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE @@ -837,8 +841,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { context.grantAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); - } - else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { + } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service @@ -847,21 +850,18 @@ else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Temporary error, and requested action REFUND_ACCOUNT // Action: Store request // New State: IDLE this.sessionData.setBuffer((Request) request.getMessage()); setState(ClientCCASessionState.IDLE, false); - } - else { + } else { logger.warn("Invalid combination for CCA Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", - new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); + new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } - } - else { // Failure + } else { // Failure if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY @@ -870,8 +870,7 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { context.indicateServiceError(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE @@ -880,8 +879,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { context.grantAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); - } - else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { + } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service @@ -890,8 +888,7 @@ else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failed CC event answer received; requested action REFUND_ACCOUNT // Action: Indicate service error and delete request @@ -900,10 +897,9 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { context.indicateServiceError(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); - } - else { + } else { logger.warn("Invalid combination for CCA Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", - new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); + new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } break; @@ -931,16 +927,14 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); - } - else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { + } else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { // Current State: PENDING_I // Event: CC initial answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); - } - else { + } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: @@ -975,16 +969,14 @@ else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN) // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); - } - else if (resultCode == END_USER_SERVICE_DENIED) { + } else if (resultCode == END_USER_SERVICE_DENIED) { // Current State: PENDING_U // Event: CC update answer received with result code END_USER_SERVICE_DENIED // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); - } - else { + } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: @@ -1015,8 +1007,7 @@ else if (resultCode == END_USER_SERVICE_DENIED) { logger.warn("Wrong event type ({}) on state {}", eventType, state); } } - } - catch (Exception e) { + } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure handling failure message for Event " + answer + " (" + eventType + ") and Request " + request, e); } @@ -1036,8 +1027,7 @@ protected void handleTxExpires(Message message) { // New State: IDLE context.indicateServiceError(this); setState(ClientCCASessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { int gatheredDDFH = this.sessionData.getGatheredDDFH(); if (gatheredDDFH == DDFH_TERMINATE_OR_BUFFER) { // Current State: PENDING_E @@ -1047,8 +1037,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { this.sessionData.setBuffer((Request) message); setState(ClientCCASessionState.IDLE, false); - } - else { + } else { // Current State: PENDING_E // Event: Tx expired; requested action DIRECT_DEBITING // Action: Grant service to end user @@ -1056,8 +1045,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { context.grantAccessOnTxExpire(this); setState(ClientCCASessionState.PENDING_EVENT); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag @@ -1105,6 +1093,9 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Action: Grant service to end user // New State: PENDING_U context.grantAccessOnTxExpire(this); + if (isSessionPersistenceEnabled()) { + stopSessionInactivityTimer(); + } break; case CCFH_TERMINATE: @@ -1145,12 +1136,10 @@ protected void dispatch() { setState(ClientCCASessionState.PENDING_BUFFERED); try { dispatchEvent(new AppRequestEventImpl(buffer)); - } - catch (Exception e) { + } catch (Exception e) { try { handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST, buffer); - } - catch (Exception e1) { + } catch (Exception e1) { logger.error("Failure handling buffer send failure", e1); } } @@ -1161,8 +1150,7 @@ protected void dispatch() { if (this.sessionData.getClientCCASessionState() == ClientCCASessionState.OPEN && eventQueue.size() > 0) { try { this.handleEvent(eventQueue.remove(0)); - } - catch (Exception e) { + } catch (Exception e) { logger.error("Failure handling queued event", e); } } @@ -1172,8 +1160,7 @@ protected void dispatch() { protected void deliverCCAnswer(JCreditControlRequest request, JCreditControlAnswer answer) { try { listener.doCreditControlAnswer(this, request, answer); - } - catch (Exception e) { + } catch (Exception e) { logger.warn("Failure delivering CCA Answer", e); } } @@ -1184,16 +1171,14 @@ protected void extractFHAVPs(JCreditControlRequest request, JCreditControlAnswer if (answer.isCreditControlFailureHandlingAVPPresent()) { this.sessionData.setGatheredCCFH(answer.getCredidControlFailureHandlingAVPValue()); } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } try { if (answer.isDirectDebitingFailureHandlingAVPPresent()) { this.sessionData.setGatheredDDFH(answer.getDirectDebitingFailureHandlingAVPValue()); } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure trying to obtain Direct-Debit-Failure-Handling AVP value", e); } if (!this.sessionData.isRequestTypeSet()) { @@ -1201,14 +1186,12 @@ protected void extractFHAVPs(JCreditControlRequest request, JCreditControlAnswer // No need to check if it exists.. it must, if not fail with exception this.sessionData.setEventBased(answer.getRequestTypeAVPValue() == EVENT_REQUEST); } - } - else if (request != null) { + } else if (request != null) { try { if (request.isRequestedActionAVPPresent()) { this.sessionData.setGatheredRequestedAction(request.getRequestedActionAVPValue()); } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure trying to obtain Request-Action AVP value", e); } @@ -1223,8 +1206,7 @@ else if (request != null) { protected void deliverRAR(ReAuthRequest request) { try { listener.doReAuthRequest(this, request); - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure delivering RAR", e); } } @@ -1271,23 +1253,18 @@ public void run() { sessionData.setTxTimerId(null); try { context.txTimerExpired(session); - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure handling TX Timer Expired", e); } JCreditControlRequest req = factory.createCreditControlRequest(request); handleEvent(new Event(Event.Type.Tx_TIMER_FIRED, req, null)); - } - catch (InternalException e) { + } catch (InternalException e) { logger.error("Internal Exception", e); - } - catch (OverloadException e) { + } catch (OverloadException e) { logger.error("Overload Exception", e); - } - catch (Exception e) { + } catch (Exception e) { logger.error("Exception", e); - } - finally { + } finally { sendAndStateLock.unlock(); } } @@ -1309,8 +1286,7 @@ public void run() { listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure processing request", e); } } @@ -1328,7 +1304,7 @@ public void run() { case JCreditControlAnswer.code: JCreditControlRequest _request = factory.createCreditControlRequest(request); JCreditControlAnswer _answer = factory.createCreditControlAnswer(answer); - extractFHAVPs(null, _answer ); + extractFHAVPs(null, _answer); handleEvent(new Event(false, _request, _answer)); break; @@ -1336,8 +1312,7 @@ public void run() { listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure processing success message", e); } } @@ -1367,8 +1342,7 @@ public boolean equals(Object obj) { if (other.sessionData != null) { return false; } - } - else if (!sessionData.equals(other.sessionData)) { + } else if (!sessionData.equals(other.sessionData)) { return false; } return true; diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java index 8960e7d1c..926ae5890 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java @@ -42,12 +42,12 @@ package org.jdiameter.client.impl.app.ro; -import java.io.Serializable; - import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.ro.ClientRoSessionState; +import java.io.Serializable; + /** * * @author Bartosz Baranowski @@ -58,9 +58,9 @@ public class ClientRoSessionDataLocalImpl extends AppSessionDataLocalImpl implem protected boolean isEventBased = true; protected boolean requestTypeSet = false; protected ClientRoSessionState state = ClientRoSessionState.IDLE; - protected Serializable txTimerId; - //protected JCreditControlRequest txTimerRequest; - protected Request txTimerRequest; + protected Serializable txTimerId = null; + protected Serializable retransmissionTimerId = null; + protected Request txTimerRequest = null; // Event Based Buffer //protected Message buffer = null; @@ -127,6 +127,14 @@ public void setTxTimerRequest(Request txTimerRequest) { this.txTimerRequest = txTimerRequest; } + public Serializable getRetransmissionTimerId() { + return retransmissionTimerId; + } + + public void setRetransmissionTimerId(Serializable retransmissionTimerId) { + this.retransmissionTimerId = retransmissionTimerId; + } + @Override public Request getBuffer() { return buffer; diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java index ca41deedb..254989ace 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java @@ -1,56 +1,47 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, TeleStax Inc. and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.client.impl.app.ro; -import java.io.Serializable; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - import org.jdiameter.api.Answer; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.EventListener; @@ -58,6 +49,7 @@ import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.NoMorePeersAvailableException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; @@ -77,17 +69,32 @@ import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; +import org.jdiameter.client.api.router.IRouter; import org.jdiameter.client.impl.app.ro.Event.Type; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.ro.ClientRoSessionState; import org.jdiameter.common.api.app.ro.IClientRoSessionContext; import org.jdiameter.common.api.app.ro.IRoMessageFactory; +import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.ro.AppRoSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Serializable; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionRequiredResCodes; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.TxTimeOut; + /** * Client Credit-Control Application session implementation * @@ -107,13 +114,18 @@ public class ClientRoSessionImpl extends AppRoSessionImpl implements ClientRoSes protected transient ClientRoSessionListener listener; protected transient IClientRoSessionContext context; protected transient IMessageParser parser; + protected transient IRouter router; // Tx Timer ----------------------------------------------------------------- - protected static final String TX_TIMER_NAME = "Ro_CLIENT_TX_TIMER"; - protected static final long TX_TIMER_DEFAULT_VALUE = 30 * 60 * 1000; // miliseconds + protected final long txTimerVal; + + // Response Timer ----------------------------------------------------------- + protected static final String RETRANSMISSION_TIMER_NAME = "Ro_CLIENT_RETRANSMISSION_TIMER"; + protected final long retransmissionTimerVal; - protected long[] authAppIds = new long[] { 4 }; + protected long[] authAppIds = new long[]{4}; + protected final Set retrRequiredErrorCodes; // Requested Action + Credit-Control and Direct-Debiting Failure-Handling --- protected static final int CCFH_TERMINATE = 0; @@ -123,11 +135,13 @@ public class ClientRoSessionImpl extends AppRoSessionImpl implements ClientRoSes private static final int DDFH_TERMINATE_OR_BUFFER = 0; private static final int DDFH_CONTINUE = 1; - // CC-Request-Type Values --------------------------------------------------- + // Requested-Action Values -------------------------------------------------- private static final int DIRECT_DEBITING = 0; private static final int REFUND_ACCOUNT = 1; private static final int CHECK_BALANCE = 2; private static final int PRICE_ENQUIRY = 3; + + // CC-Request-Type --------------------------------------------------------- private static final int EVENT_REQUEST = 4; // Error Codes -------------------------------------------------------------- @@ -152,9 +166,9 @@ public class ClientRoSessionImpl extends AppRoSessionImpl implements ClientRoSes // Session Based Queue protected ArrayList eventQueue = new ArrayList(); - public ClientRoSessionImpl(IClientRoSessionData sessionData, IRoMessageFactory fct, ISessionFactory sf, ClientRoSessionListener lst, - IClientRoSessionContext ctx, StateChangeListener stLst) { - super(sf, sessionData); + public ClientRoSessionImpl(IClientRoSessionData sessionData, IRoMessageFactory fct, ISessionDatasource sds, ISessionFactory sf, + ClientRoSessionListener lst, IClientRoSessionContext ctx, StateChangeListener stLst) { + super(sds, sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } @@ -171,10 +185,19 @@ public ClientRoSessionImpl(IClientRoSessionData sessionData, IRoMessageFactory f this.factory = fct; IContainer icontainer = sf.getContainer(); + this.parser = icontainer.getAssemblerFacility().getComponentInstance(IMessageParser.class); + this.router = icontainer.getAssemblerFacility().getComponentInstance(IRouter.class); + this.txTimerVal = icontainer.getConfiguration().getLongValue(TxTimeOut.ordinal(), (Long) TxTimeOut.defValue()); + this.retransmissionTimerVal = icontainer.getConfiguration().getLongValue(RetransmissionTimeOut.ordinal(), (Long) RetransmissionTimeOut.defValue()); - super.addStateChangeNotification(stLst); + Set tmpErrCodes = new HashSet<>(); + for (int val : icontainer.getConfiguration().getIntArrayValue(RetransmissionRequiredResCodes.ordinal(), new int[0])) { + tmpErrCodes.add(new Long(val)); + } + this.retrRequiredErrorCodes = Collections.unmodifiableSet(tmpErrCodes); + super.addStateChangeNotification(stLst); } protected int getLocalCCFH() { @@ -187,12 +210,11 @@ protected int getLocalDDFH() { @Override public void sendCreditControlRequest(RoCreditControlRequest request) - throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { try { extractFHAVPs(request, null); this.handleEvent(new Event(true, request, null)); - } - catch (AvpDataException e) { + } catch (AvpDataException e) { throw new InternalException(e); } } @@ -237,12 +259,11 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce // Event: Client or device requests a one-time service // Action: Send CC event request, start Tx // New State: PENDING_E - startTx((RoCreditControlRequest) localEvent.getRequest()); + startTx(localEvent.getRequest().getMessage()); setState(ClientRoSessionState.PENDING_EVENT); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table logger.debug("Failure handling send event request", e); handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); @@ -272,8 +293,7 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce } deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); - } - catch (AvpDataException e) { + } catch (AvpDataException e) { logger.debug("Failure handling received answer event", e); setState(ClientRoSessionState.IDLE, false); } @@ -311,11 +331,9 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce dispatch(); return true; - } - catch (Exception e) { + } catch (Exception e) { throw new InternalException(e); - } - finally { + } finally { sendAndStateLock.unlock(); } } @@ -335,12 +353,13 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx // Event: Client or device requests access/service // Action: Send CC initial request, start Tx // New State: PENDING_I - startTx((RoCreditControlRequest) localEvent.getRequest()); + startTx(localEvent.getRequest().getMessage()); setState(ClientRoSessionState.PENDING_INITIAL); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (NoMorePeersAvailableException nmpae) { + handlePeerUnavailability(localEvent.getRequest().getMessage(), nmpae); + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } @@ -363,14 +382,31 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx // New State: OPEN stopTx(); setState(ClientRoSessionState.OPEN); - } - else if (isProvisional(resultCode) || isFailure(resultCode)) { + //Session persistence record shall be created after a peer had answered + //the first (initial) request for that session + if (isSessionPersistenceEnabled()) { + initSessionPersistenceContext(localEvent.getRequest(), localEvent.getAnswer()); + startSessionInactivityTimer(); + } + } else if (retrRequiredErrorCodes.contains(resultCode)) { + handleRetransmissionDueToError(eventType, localEvent.getRequest().getMessage()); + break; + } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType); } + deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: - handleTxExpires(localEvent.getRequest().getMessage()); + if (isRetransmissionRequired()) { + handleRetransmissionDueToTimeout(eventType, localEvent.getRequest().getMessage()); + } + else { + handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); + } + break; + case RETRANSMISSION_TIMER_FIRED: + handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); break; case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: @@ -413,12 +449,16 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // Event: RAR received // Action: Send RAA followed by CC update request, start Tx // New State: PENDING_U - startTx((RoCreditControlRequest) localEvent.getRequest()); + startTx(localEvent.getRequest().getMessage()); + if (isSessionPersistenceEnabled()) { + startSessionInactivityTimer(); + } setState(ClientRoSessionState.PENDING_UPDATE); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (NoMorePeersAvailableException nmpae) { + handlePeerUnavailability(localEvent.getRequest().getMessage(), nmpae); + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } @@ -438,11 +478,18 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // Event: User service terminated // Action: Send CC termination request // New State: PENDING_T + + // In all cases start Tx in order to assure failover + startTx(localEvent.getRequest().getMessage()); + if (isSessionPersistenceEnabled()) { + stopSessionInactivityTimer(); + } setState(ClientRoSessionState.PENDING_TERMINATION); try { dispatchEvent(localEvent.getRequest()); - } - catch (Exception e) { + } catch (NoMorePeersAvailableException nmpae) { + handlePeerUnavailability(localEvent.getRequest().getMessage(), nmpae); + } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -452,8 +499,7 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { case SEND_RAA: try { dispatchEvent(localEvent.getAnswer()); - } - catch (Exception e) { + } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -476,16 +522,26 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // New State: OPEN stopTx(); setState(ClientRoSessionState.OPEN); - } - else if (isProvisional(resultCode) || isFailure(resultCode)) { + } else if (retrRequiredErrorCodes.contains(resultCode)) { + handleRetransmissionDueToError(eventType, localEvent.getRequest().getMessage()); + break; + } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType); } + deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: - handleTxExpires(localEvent.getRequest().getMessage()); + if (isRetransmissionRequired()) { + handleRetransmissionDueToTimeout(eventType, localEvent.getRequest().getMessage()); + } + else { + handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); + } + break; + case RETRANSMISSION_TIMER_FIRED: + handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); break; - case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: // Current State: PENDING_U @@ -509,8 +565,7 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // New State: PENDING_U try { dispatchEvent(localEvent.getAnswer()); - } - catch (Exception e) { + } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -528,8 +583,7 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { // New State: PENDING_T dispatchEvent(localEvent.getRequest()); // No transition - } - catch (Exception e) { + } catch (Exception e) { // This handles failure to send in PendingI state in FSM table // handleSendFailure(e, eventType); } @@ -547,9 +601,26 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { //FIXME: Alex broke this, setting back "true" ? //setState(ClientRoSessionState.IDLE, false); + long resultCode = ((AppAnswerEvent) localEvent.getAnswer()).getResultCodeAvp().getUnsigned32(); + if (retrRequiredErrorCodes.contains(resultCode)) { + handleRetransmissionDueToError(eventType, localEvent.getRequest().getMessage()); + break; + } + deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); setState(ClientRoSessionState.IDLE, true); break; + case Tx_TIMER_FIRED: + if (isRetransmissionRequired()) { + handleRetransmissionDueToTimeout(eventType, localEvent.getRequest().getMessage()); + } + else { + handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); + } + break; + case RETRANSMISSION_TIMER_FIRED: + handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); + break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; @@ -563,11 +634,9 @@ else if (isProvisional(resultCode) || isFailure(resultCode)) { dispatch(); return true; - } - catch (Exception e) { + } catch (Exception e) { throw new InternalException(e); - } - finally { + } finally { sendAndStateLock.unlock(); } } @@ -596,44 +665,68 @@ public void timeoutExpired(Request request) { if (request.getCommandCode() == RoCreditControlAnswer.code) { try { sendAndStateLock.lock(); + stopTx(); handleSendFailure(null, null, request); - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure processing timeout message for request", e); - } - finally { + } finally { sendAndStateLock.unlock(); } } } - protected void startTx(RoCreditControlRequest request) { - long txTimerValue = context.getDefaultTxTimerValue(); - if (txTimerValue < 0) { - txTimerValue = TX_TIMER_DEFAULT_VALUE; + protected void startTx(Message message) { + stopTx(false); + if(logger.isDebugEnabled()) { + logger.debug("Scheduling Tx timer in [{}] ms", this.txTimerVal); } - stopTx(); - - logger.debug("Scheduling TX Timer {}", txTimerValue); - //this.txFuture = scheduler.schedule(new TxTimerTask(this, request), txTimerValue, TimeUnit.SECONDS); try { - sessionData.setTxTimerRequest((Request) request.getMessage()); - sessionData.setTxTimerId(this.timerFacility.schedule(this.sessionData.getSessionId(), TX_TIMER_NAME, TX_TIMER_DEFAULT_VALUE)); - } - catch (Exception e) { + sessionData.setTxTimerRequest((Request) message); + sessionData.setTxTimerId(this.timerFacility.schedule(this.sessionData.getSessionId(), TX_TIMER_NAME, this.txTimerVal)); + } catch (Exception e) { throw new IllegalArgumentException("Failed to store request.", e); } } - protected void stopTx() { + protected void stopTx(boolean stopDependant) { Serializable txTimerId = this.sessionData.getTxTimerId(); if (txTimerId != null) { + if (stopDependant) { + stopFailoverStopTimer(); + } + if(logger.isDebugEnabled()) { + logger.debug("Stopping Tx timer [{}]", txTimerId); + } timerFacility.cancel(txTimerId); sessionData.setTxTimerId(null); sessionData.setTxTimerRequest(null); } } + protected void stopTx() { + stopTx(true); + } + + protected void startFailoverStopTimer() { + long timerVal = this.retransmissionTimerVal - this.txTimerVal; + if (timerVal <= 0) { + logger.warn("Value of Tx timer cannot exceed failover stop timer: [{}] vs. [{}] (taking default values)", this.txTimerVal, this.retransmissionTimerVal); + timerVal = this.txTimerVal + (((Long) RetransmissionTimeOut.defValue()) - ((Long) TxTimeOut.defValue())); + } + logger.debug("Scheduling failover stop timer in [{}] ms", timerVal); + stopFailoverStopTimer(); + sessionData.setRetransmissionTimerId(this.timerFacility.schedule(this.sessionData.getSessionId(), RETRANSMISSION_TIMER_NAME, timerVal)); + } + + protected void stopFailoverStopTimer() { + Serializable failoverStopTimerId = this.sessionData.getRetransmissionTimerId(); + if (failoverStopTimerId != null) { + logger.debug("Stopping failover stop timer [{}]", failoverStopTimerId); + timerFacility.cancel(failoverStopTimerId); + sessionData.setRetransmissionTimerId(null); + } + } + /* (non-Javadoc) * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @@ -641,6 +734,17 @@ protected void stopTx() { public void onTimer(String timerName) { if (timerName.equals(TX_TIMER_NAME)) { new TxTimerTask(this, sessionData.getTxTimerRequest()).run(); + } else if (timerName.equals(RETRANSMISSION_TIMER_NAME)) { + new RetransmissionTimerTask(this, sessionData.getTxTimerRequest()).run(); + } else { + try { + sendAndStateLock.lock(); + super.onTimer(timerName); + } catch (Exception ex) { + logger.error("Cannot properly handle timer expiry", ex); + } finally { + sendAndStateLock.unlock(); + } } } @@ -655,7 +759,7 @@ protected void setState(ClientRoSessionState newState, boolean release) { IAppSessionState oldState = state; sessionData.setClientRoSessionState(newState); for (StateChangeListener i : stateListeners) { - i.stateChanged(this,(Enum) oldState, (Enum) newState); + i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ClientRoSessionState.IDLE) { @@ -663,9 +767,16 @@ protected void setState(ClientRoSessionState newState, boolean release) { this.release(); } stopTx(); + + if (isSessionPersistenceEnabled()) { + stopSessionInactivityTimer(); + if (!release) { + String oldPeer = flushSessionPersistenceContext(); + logger.debug("Session state reset, routing context for peer [{}] was removed from session [{}]", oldPeer, this.getSessionId()); + } + } } - } - catch (Exception e) { + } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure switching to state " + sessionData.getClientRoSessionState() + " (release=" + release + ")", e); } @@ -679,20 +790,18 @@ public void release() { this.sendAndStateLock.lock(); this.stopTx(); super.release(); - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failed to release session", e); - } - finally { + } finally { this.sendAndStateLock.unlock(); } - } - else { + } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void handleSendFailure(Exception e, Event.Type eventType, Message request) throws Exception { + logger.warn("Failed to send message", e); logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""}); try { ClientRoSessionState state = sessionData.getClientRoSessionState(); @@ -708,8 +817,7 @@ protected void handleSendFailure(Exception e, Event.Type eventType, Message requ // New State: IDLE setState(ClientRoSessionState.IDLE); context.indicateServiceError(this); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { switch (getLocalDDFH()) { case DDFH_TERMINATE_OR_BUFFER: // Current State: PENDING_E @@ -731,8 +839,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { default: logger.warn("Invalid Direct-Debiting-Failure-Handling AVP value {}", getLocalDDFH()); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag @@ -740,8 +847,7 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { setState(ClientRoSessionState.IDLE, false); request.setReTransmitted(true); sessionData.setBuffer((Request) request); - } - else { + } else { logger.warn("Invalid Requested-Action AVP value {}", gatheredRequestedAction); } break; @@ -790,8 +896,7 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { break; } } - } - finally { + } finally { dispatch(); } } @@ -815,16 +920,14 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl context.denyAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { + } else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { // Current State: PENDING_E // Event: Failed answer or answer received w/ result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx expired // Action: - // New State: IDLE setState(ClientRoSessionState.IDLE); } - } - else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { + } else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { // Current State: PENDING_E // Event: CC event answer received with result code CREDIT_CONTROL_NOT_APPLICABLE; requested action DIRECT_DEBITING // Action: Grant service to end user @@ -832,8 +935,7 @@ else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } - else if (temporaryErrorCodes.contains(resultCode)) { + } else if (temporaryErrorCodes.contains(resultCode)) { if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY @@ -842,8 +944,7 @@ else if (temporaryErrorCodes.contains(resultCode)) { context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE @@ -852,8 +953,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } - else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { + } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service @@ -862,21 +962,18 @@ else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Temporary error, and requested action REFUND_ACCOUNT // Action: Store request // New State: IDLE sessionData.setBuffer((Request) request); setState(ClientRoSessionState.IDLE, false); - } - else { + } else { logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", - new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); + new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } - } - else { // Failure + } else { // Failure if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY @@ -885,8 +982,7 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE @@ -895,8 +991,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } - else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { + } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service @@ -905,8 +1000,7 @@ else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failed CC event answer received; requested action REFUND_ACCOUNT // Action: Indicate service error and delete request @@ -915,10 +1009,9 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } - else { + } else { logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", - new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); + new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } break; @@ -946,16 +1039,14 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } - else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { + } else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { // Current State: PENDING_I // Event: CC initial answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } - else { + } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: @@ -990,16 +1081,14 @@ else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN) // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } - else if (resultCode == END_USER_SERVICE_DENIED) { + } else if (resultCode == END_USER_SERVICE_DENIED) { // Current State: PENDING_U // Event: CC update answer received with result code END_USER_SERVICE_DENIED // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } - else { + } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: @@ -1030,8 +1119,7 @@ else if (resultCode == END_USER_SERVICE_DENIED) { logger.warn("Wrong event type ({}) on state {}", eventType, state); } } - } - catch (Exception e) { + } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure handling failure message for Event " + event + " (" + eventType + ") and Request " + request, e); } @@ -1051,8 +1139,7 @@ protected void handleTxExpires(Message message) { // New State: IDLE context.indicateServiceError(this); setState(ClientRoSessionState.IDLE); - } - else if (gatheredRequestedAction == DIRECT_DEBITING) { + } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (sessionData.getGatheredDDFH() == DDFH_TERMINATE_OR_BUFFER) { // Current State: PENDING_E // Event: Temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER; Tx expired @@ -1060,8 +1147,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { // New State: IDLE sessionData.setBuffer((Request) message); setState(ClientRoSessionState.IDLE, false); - } - else { + } else { // Current State: PENDING_E // Event: Tx expired; requested action DIRECT_DEBITING // Action: Grant service to end user @@ -1069,8 +1155,7 @@ else if (gatheredRequestedAction == DIRECT_DEBITING) { context.grantAccessOnTxExpire(this); setState(ClientRoSessionState.PENDING_EVENT); } - } - else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag @@ -1141,6 +1226,71 @@ else if (gatheredRequestedAction == REFUND_ACCOUNT) { break; } } + + this.release(); + } + + protected void handleRetransmissionFailure(RoCreditControlRequest req) { + try { + deliverRequestTimeout(req.getMessage()); + resetMessageStatus((IMessage) req.getMessage()); + } catch (InternalException e) { + logger.error("Cannot remove the expired message from either peer or rouoter tables for session [{}]", this.getSessionId()); + } + + setState(ClientRoSessionState.IDLE, true); + } + + protected void handlePeerUnavailability(Message msg, NoMorePeersAvailableException nmpae) { + deliverPeerUnavailabilityError(msg, nmpae); + resetMessageStatus(msg); + setState(ClientRoSessionState.IDLE, true); + } + + protected void handleRetransmission(Type eventType, IMessage msg, boolean tFlagSetting) { + msg.setReTransmitted(tFlagSetting); + if (this.sessionData.getRetransmissionTimerId() == null) { + startFailoverStopTimer(); + } + + if (isSessionPersistenceEnabled()) { + String oldPeer = flushSessionPersistenceContext(); + logger.debug("Routing context for peer [{}] was removed from session [{}] due to retransmission", oldPeer, this.getSessionId()); + } + + resetMessageStatus(msg); + startTx(msg); + + try { + dispatchEvent(msg); + } catch (NoMorePeersAvailableException nmpae) { + handlePeerUnavailability(msg, nmpae); + } catch (Exception e1) { + logger.error("Cannot retransmit an old request", e1); + try { + handleSendFailure(e1, eventType, msg); + } catch (Exception e2) { + logger.error("Failure handling error", e2); + } + } + } + + protected void handleRetransmissionDueToError(Type eventType, Message msg) { + IMessage imsg = (IMessage) msg; + + if (!imsg.isRetransmissionAllowed()) { + NoMorePeersAvailableException cause = new NoMorePeersAvailableException("No more peers available for retransmission"); + cause.setSessionPersistentRoutingEnabled(router.isSessionAware()); + handlePeerUnavailability(msg, cause); + return; + } + + handleRetransmission(eventType, imsg, false); + imsg.decrementNumberOfRetransAllowed(); + } + + protected void handleRetransmissionDueToTimeout(Type eventType, Message msg) { + handleRetransmission(eventType, (IMessage) msg, true); } /** @@ -1159,12 +1309,10 @@ protected void dispatch() { setState(ClientRoSessionState.PENDING_BUFFERED); try { dispatchEvent(new AppRequestEventImpl(buffer)); - } - catch (Exception e) { + } catch (Exception e) { try { handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST, buffer); - } - catch (Exception e1) { + } catch (Exception e1) { logger.error("Failure handling buffer send failure", e1); } } @@ -1175,8 +1323,7 @@ protected void dispatch() { if (sessionData.getClientRoSessionState() == ClientRoSessionState.OPEN && eventQueue.size() > 0) { try { this.handleEvent(eventQueue.remove(0)); - } - catch (Exception e) { + } catch (Exception e) { logger.error("Failure handling queued event", e); } } @@ -1184,32 +1331,61 @@ protected void dispatch() { } protected void deliverRoAnswer(RoCreditControlRequest request, RoCreditControlAnswer answer) { + logger.debug("Propagating answer event to listener [{}] on {} session", listener, isValid() ? "valid" : "invalid"); try { if (isValid()) { listener.doCreditControlAnswer(this, request, answer); } - } - catch (Exception e) { + } catch (Exception e) { logger.warn("Failure delivering Ro Answer", e); } } + protected void deliverRAR(ReAuthRequest request) { + logger.debug("Propagating RAR event to listener [{}] on {} session", listener, isValid() ? "valid" : "invalid"); + try { + listener.doReAuthRequest(this, request); + } catch (Exception e) { + logger.warn("Failure delivering RAR", e); + } + } + + protected void deliverRequestTimeout(Message msg) { + logger.debug("Propagating timeout event to listener [{}] on {} session", listener, isValid() ? "valid" : "invalid"); + try { + if (isValid()) { + listener.doRequestTimeout(this, msg, ((IMessage) msg).getPeer()); + } + } catch (Exception e) { + logger.warn("Failure delivering request timeout", e); + } + } + + protected void deliverPeerUnavailabilityError(Message msg, NoMorePeersAvailableException cause) { + logger.debug("Propagating peer unavailability error event to listener [{}] on {} session", listener, isValid() ? "valid" : "invalid"); + try { + if (isValid()) { + listener.doPeerUnavailability(cause, this, msg, ((IMessage) msg).getPeer()); + } + } catch (Exception e) { + logger.warn("Failure delivering peer unavailability error", e); + } + } + protected void extractFHAVPs(RoCreditControlRequest request, RoCreditControlAnswer answer) throws AvpDataException { if (answer != null) { try { if (answer.isCreditControlFailureHandlingAVPPresent()) { sessionData.setGatheredCCFH(answer.getCredidControlFailureHandlingAVPValue()); } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } try { if (answer.isDirectDebitingFailureHandlingAVPPresent()) { sessionData.setGatheredDDFH(answer.getDirectDebitingFailureHandlingAVPValue()); } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure trying to obtain Direct-Debit-Failure-Handling AVP value", e); } if (!sessionData.isRequestTypeSet()) { @@ -1217,14 +1393,12 @@ protected void extractFHAVPs(RoCreditControlRequest request, RoCreditControlAnsw // No need to check if it exists.. it must, if not fail with exception sessionData.setEventBased(answer.getRequestTypeAVPValue() == EVENT_REQUEST); } - } - else if (request != null) { + } else if (request != null) { try { if (request.isRequestedActionAVPPresent()) { sessionData.setGatheredRequestedAction(request.getRequestedActionAVPValue()); } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure trying to obtain Request-Action AVP value", e); } @@ -1236,17 +1410,15 @@ else if (request != null) { } } - protected void deliverRAR(ReAuthRequest request) { - try { - listener.doReAuthRequest(this, request); - } - catch (Exception e) { - logger.debug("Failure delivering RAR", e); + protected void dispatchEvent(IMessage message) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + if (message.isRequest()) { + message.setRetransmissionSupervised(true); } + session.send(message, this); } protected void dispatchEvent(AppEvent event) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { - session.send(event.getMessage(), this); + dispatchEvent((IMessage) event.getMessage()); } protected boolean isProvisional(long resultCode) { @@ -1261,6 +1433,10 @@ protected boolean isFailure(long code) { return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && code < 6000)) && !temporaryErrorCodes.contains(code)); } + protected boolean isRetransmissionRequired() { + return (getLocalCCFH() == CCFH_CONTINUE || getLocalCCFH() == CCFH_RETRY_AND_TERMINATE); + } + /* (non-Javadoc) * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @@ -1269,7 +1445,6 @@ public boolean isReplicable() { return true; } - private class TxTimerTask implements Runnable { private ClientRoSession session = null; private Request request = null; @@ -1284,28 +1459,46 @@ private TxTimerTask(ClientRoSession session, Request request) { public void run() { try { sendAndStateLock.lock(); - logger.debug("Fired TX Timer"); + logger.debug("Fired Tx timer"); sessionData.setTxTimerId(null); sessionData.setTxTimerRequest(null); - try { - context.txTimerExpired(session); - } - catch (Exception e) { - logger.debug("Failure handling TX Timer Expired", e); - } + RoCreditControlRequest req = factory.createCreditControlRequest(request); handleEvent(new Event(Event.Type.Tx_TIMER_FIRED, req, null)); - } - catch (InternalException e) { + } catch (InternalException e) { logger.error("Internal Exception", e); - } - catch (OverloadException e) { + } catch (OverloadException e) { logger.error("Overload Exception", e); - } - catch (Exception e) { + } catch (Exception e) { logger.error("Exception", e); + } finally { + sendAndStateLock.unlock(); } - finally { + } + } + + private class RetransmissionTimerTask implements Runnable { + private Request request = null; + + private RetransmissionTimerTask(ClientRoSession session, Request request) { + super(); + this.request = request; + } + + public void run() { + try { + sendAndStateLock.lock(); + logger.debug("Fired failover stop timer"); + stopTx(false); + sessionData.setRetransmissionTimerId(null); + handleEvent(new Event(Event.Type.RETRANSMISSION_TIMER_FIRED, factory.createCreditControlRequest(request), null)); + } catch (InternalException e) { + logger.error("Internal Exception", e); + } catch (OverloadException e) { + logger.error("Overload Exception", e); + } catch (Exception e) { + logger.error("Exception", e); + } finally { sendAndStateLock.unlock(); } } @@ -1317,8 +1510,7 @@ private Message messageFromBuffer(ByteBuffer request) throws InternalException { try { m = parser.createMessage(request); return m; - } - catch (AvpDataException e) { + } catch (AvpDataException e) { throw new InternalException("Failed to decode message.", e); } } @@ -1328,12 +1520,21 @@ private Message messageFromBuffer(ByteBuffer request) throws InternalException { private ByteBuffer messageToBuffer(IMessage msg) throws InternalException { try { return parser.encodeMessage(msg); - } - catch (ParseException e) { + } catch (ParseException e) { throw new InternalException("Failed to encode message.", e); } } + private void resetMessageStatus(Message message) { + IMessage msg = (IMessage) message; + msg.clearTimer(); + msg.setState(IMessage.STATE_NOT_SENT); + if (msg.getPeer() != null) { + msg.getPeer().remMessage(msg); + } + router.garbageCollectRequestRouteInfo(msg); + } + private class RequestDelivery implements Runnable { ClientRoSession session; Request request; @@ -1350,8 +1551,7 @@ public void run() { listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure processing request", e); } } @@ -1369,7 +1569,7 @@ public void run() { case RoCreditControlAnswer.code: RoCreditControlRequest _request = factory.createCreditControlRequest(request); RoCreditControlAnswer _answer = factory.createCreditControlAnswer(answer); - extractFHAVPs(null, _answer ); + extractFHAVPs(null, _answer); handleEvent(new Event(false, _request, _answer)); break; @@ -1377,8 +1577,7 @@ public void run() { listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Failure processing success message", e); } } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/Event.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/Event.java index 62ea2ea3a..0285b65e9 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/Event.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/Event.java @@ -61,7 +61,7 @@ public enum Type { SEND_INITIAL_REQUEST, RECEIVED_INITIAL_ANSWER, SEND_UPDATE_REQUEST, RECEIVED_UPDATE_ANSWER, SEND_TERMINATE_REQUEST, RECEIVED_TERMINATED_ANSWER, - RECEIVED_RAR, SEND_RAA, Tx_TIMER_FIRED, + RECEIVED_RAR,SEND_RAA, Tx_TIMER_FIRED, RETRANSMISSION_TIMER_FIRED, SEND_EVENT_REQUEST, RECEIVE_EVENT_ANSWER; } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java index a9611a01a..a729a31e1 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java @@ -42,12 +42,12 @@ package org.jdiameter.client.impl.app.ro; -import java.io.Serializable; - import org.jdiameter.api.Request; import org.jdiameter.common.api.app.ro.ClientRoSessionState; import org.jdiameter.common.api.app.ro.IRoSessionData; +import java.io.Serializable; + /** * * @author Bartosz Baranowski @@ -75,6 +75,10 @@ public interface IClientRoSessionData extends IRoSessionData { void setTxTimerRequest(Request txTimerRequest); + Serializable getRetransmissionTimerId(); + + void setRetransmissionTimerId(Serializable retransmissionTimerId); + Request getBuffer(); void setBuffer(Request buffer); diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java index 3415b6cec..5ec8db101 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java @@ -191,7 +191,7 @@ public void connectionOpened(String connKey) { public void connectionClosed(String connKey, List notSent) { logger.debug("Connection from {} is closed", uri); for (IMessage request : peerRequests.values()) { - if (request.getState() == IMessage.STATE_SENT) { + if (request.getState() == IMessage.STATE_SENT && !request.isRetransmissionSupervised()) { request.setReTransmitted(true); request.setState(IMessage.STATE_NOT_SENT); try { @@ -632,7 +632,7 @@ public boolean isConnected() { @Override public String toString() { - return "CPeer{" + "Uri=" + uri + "; State=" + (fsm != null ? fsm.getState(PeerState.class) : "n/a") + "; Con=" + connection + "}"; + return "CPeer{" + "Uri=" + uri + "; State=" + (fsm != null ? fsm.getState(PeerState.class) : "n/a") + "; Rating=" + rating + "; Con=" + connection + "}"; } protected void fillIPAddressTable(IMessage message) { diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/EmptyConfiguration.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/EmptyConfiguration.java index 6b9019d6f..784015b40 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/EmptyConfiguration.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/EmptyConfiguration.java @@ -42,6 +42,10 @@ package org.jdiameter.client.impl.helpers; +import org.jdiameter.api.Configuration; + +import java.util.concurrent.ConcurrentHashMap; + import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentConfiguration; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentRedirect; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalConnectionClass; @@ -60,10 +64,6 @@ import static org.jdiameter.client.impl.helpers.Parameters.ExtensionName; import static org.jdiameter.client.impl.helpers.Parameters.Extensions; -import java.util.concurrent.ConcurrentHashMap; - -import org.jdiameter.api.Configuration; - /** * This class allow create configuration class for stack * @@ -212,7 +212,13 @@ public byte[] getByteArrayValue(int i, byte[] bytes) { /** * @see org.jdiameter.api.Configuration class */ - @Override + public int[] getIntArrayValue(int i, int[] ints) { + return (int[]) (isAttributeExist(i) ? elements.get(i) : ints); + } + + /** + * @see org.jdiameter.api.Configuration class + */ public boolean getBooleanValue(int i, boolean b) { return (Boolean) (isAttributeExist(i) ? elements.get(i) : b); } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java index cb568947d..c07c3b0fa 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java @@ -398,6 +398,30 @@ public class Parameters extends Ordinal { */ public static final Parameters DictionaryReceiveLevel = new Parameters("DictionaryReceiveLevel", String.class, "OFF"); + /** + * Maximum session inactivity time specified in seconds which defines how much time + * the persistence record should be kept if there is no request sent within a session. + * Irrelevant when session persistent routing is not enabled. + */ + public static final Parameters SessionInactivityTimeOut = new Parameters("SessionInactivityTimeOut", Integer.class, 600); + + /** + * Tx timer as described in chapter 13. of RFC 4006: + *
      The Tx timer is introduced to control the waiting time in the client in the Pending state. The recommended value is 10 seconds.
      + */ + public static final Parameters TxTimeOut = new Parameters("TxTimeOut", Long.class, 10000L); + + /** + * Retransmission stop timer which defines how long the stack should wait for the answer message from remote peers and carry on with + * retransmissions in case of delivery failures. + */ + public static final Parameters RetransmissionTimeOut = new Parameters("RetransmissionTimeOut", Long.class, 45000L); + + /** + * Array of result codes which make an initial request to be retransmitted to another remote peer. + */ + public static final Parameters RetransmissionRequiredResCodes = new Parameters("RetransmissionRequiredResCodes", Object.class); + /** * Return all parameters as iterator * diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java index 94286661f..8c13c50d2 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java @@ -42,6 +42,28 @@ package org.jdiameter.client.impl.helpers; +import org.jdiameter.api.Configuration; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentConfiguration; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentRedirect; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalConcurrentEntityFactory; @@ -103,12 +125,14 @@ import static org.jdiameter.client.impl.helpers.Parameters.RealmEntry; import static org.jdiameter.client.impl.helpers.Parameters.RealmTable; import static org.jdiameter.client.impl.helpers.Parameters.RecTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionRequiredResCodes; import static org.jdiameter.client.impl.helpers.Parameters.SDEnableSessionCreation; import static org.jdiameter.client.impl.helpers.Parameters.SDName; import static org.jdiameter.client.impl.helpers.Parameters.SDProtocol; import static org.jdiameter.client.impl.helpers.Parameters.SDUseClientMode; import static org.jdiameter.client.impl.helpers.Parameters.Security; import static org.jdiameter.client.impl.helpers.Parameters.SecurityRef; +import static org.jdiameter.client.impl.helpers.Parameters.SessionInactivityTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.Statistics; import static org.jdiameter.client.impl.helpers.Parameters.StatisticsActiveList; import static org.jdiameter.client.impl.helpers.Parameters.StatisticsEnabled; @@ -123,6 +147,7 @@ import static org.jdiameter.client.impl.helpers.Parameters.ThreadPoolPriority; import static org.jdiameter.client.impl.helpers.Parameters.ThreadPoolSize; import static org.jdiameter.client.impl.helpers.Parameters.TrustData; +import static org.jdiameter.client.impl.helpers.Parameters.TxTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; import static org.jdiameter.client.impl.helpers.Parameters.VendorId; import static org.jdiameter.server.impl.helpers.Parameters.RealmEntryExpTime; @@ -130,29 +155,7 @@ import static org.jdiameter.server.impl.helpers.Parameters.RealmHosts; import static org.jdiameter.server.impl.helpers.Parameters.RealmLocalAction; import static org.jdiameter.server.impl.helpers.Parameters.RealmName; - -import java.io.File; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.Source; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import org.jdiameter.api.Configuration; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; +import static org.jdiameter.server.impl.helpers.Parameters.RetransmissionTimeOut; /** * This class provide loading and verification configuration for client from XML file @@ -176,9 +179,9 @@ public XMLConfiguration(InputStream in) throws Exception { /** * Create instance of class and load file from defined input stream * - * @param in input stream + * @param in input stream * @param attributes attributes for DocumentBuilderFactory - * @param features features for DocumentBuilderFactory + * @param features features for DocumentBuilderFactory * @throws Exception */ public XMLConfiguration(InputStream in, Hashtable attributes, Hashtable features) throws Exception { @@ -198,9 +201,9 @@ public XMLConfiguration(String filename) throws Exception { /** * Create instance of class and load file from defined input stream * - * @param filename configuration file name + * @param filename configuration file name * @param attributes attributes for DocumentBuilderFactory - * @param features features for DocumentBuilderFactory + * @param features features for DocumentBuilderFactory * @throws Exception */ public XMLConfiguration(String filename, Hashtable attributes, Hashtable features) throws Exception { @@ -225,12 +228,10 @@ protected XMLConfiguration(Object in, Hashtable attributes, Hash if (in instanceof InputStream) { document = builder.parse((InputStream) in); - } - else if (in instanceof String) { + } else if (in instanceof String) { document = builder.parse(new File((String) in)); - } - else { - throw new Exception("Unknown type of input data"); + } else { + throw new Exception("Unknown type of input data"); } validate(document); processing(document); @@ -251,17 +252,13 @@ protected void processing(Document document) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("LocalPeer")) { addLocalPeer(c.item(i)); - } - else if (nodeName.equals("Parameters")) { + } else if (nodeName.equals("Parameters")) { addParameters(c.item(i)); - } - else if (nodeName.equals("Network")) { + } else if (nodeName.equals("Network")) { addNetwork(c.item(i)); - } - else if (nodeName.equals("Security")) { + } else if (nodeName.equals("Security")) { addSecurity(c.item(i)); - } - else if (nodeName.equals("Extensions")) { + } else if (nodeName.equals("Extensions")) { addExtensions(c.item(i)); } } @@ -323,11 +320,9 @@ protected Configuration addApplication(Node node) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("VendorId")) { e.add(VendorId, getLongValue(c.item(i))); - } - else if (nodeName.equals("AuthApplId")) { + } else if (nodeName.equals("AuthApplId")) { e.add(AuthApplId, getLongValue(c.item(i))); - } - else if (nodeName.equals("AcctApplId")) { + } else if (nodeName.equals("AcctApplId")) { e.add(AcctApplId, getLongValue(c.item(i))); } } @@ -340,49 +335,55 @@ protected void addParameters(Node node) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("UseUriAsFqdn")) { add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); - } - else if (nodeName.equals("QueueSize")) { + } else if (nodeName.equals("QueueSize")) { add(QueueSize, getIntValue(c.item(i))); - } - else if (nodeName.equals("MessageTimeOut")) { + } else if (nodeName.equals("MessageTimeOut")) { add(MessageTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("StopTimeOut")) { + } else if (nodeName.equals("StopTimeOut")) { add(StopTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("CeaTimeOut")) { + } else if (nodeName.equals("CeaTimeOut")) { add(CeaTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("IacTimeOut")) { + } else if (nodeName.equals("IacTimeOut")) { add(IacTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("DwaTimeOut")) { + } else if (nodeName.equals("DwaTimeOut")) { add(DwaTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("DpaTimeOut")) { + } else if (nodeName.equals("DpaTimeOut")) { add(DpaTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("RecTimeOut")) { + } else if (nodeName.equals("RecTimeOut")) { add(RecTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("PeerFSMThreadCount")) { + } else if (nodeName.equals("PeerFSMThreadCount")) { add(PeerFSMThreadCount, getIntValue(c.item(i))); - } - else if (nodeName.equals("Statistics")) { + } else if (nodeName.equals("Statistics")) { addStatisticLogger(Statistics, c.item(i)); - } - else if (nodeName.equals("Concurrent")) { + } else if (nodeName.equals("Concurrent")) { addConcurrent(Concurrent, c.item(i)); - } - else if (nodeName.equals("Dictionary")) { + } else if (nodeName.equals("Dictionary")) { addDictionary(Dictionary, c.item(i)); - } - else { + } else if (nodeName.equals("SessionInactivityTimeOut")) { + add(SessionInactivityTimeOut, getIntValue(c.item(i))); + } else if (nodeName.equals("TxTimeOut")) { + add(TxTimeOut, getLongValue(c.item(i))); + } else if (nodeName.equals("RetransmissionTimeOut")) { + add(RetransmissionTimeOut, getLongValue(c.item(i))); + } else if (nodeName.equals("RetransmissionRequiredResCodes")) { + addRetransmissionRequiredResCodes(c.item(i)); + } else { appendOtherParameter(c.item(i)); } } } + protected void addRetransmissionRequiredResCodes(Node node) { + String[] codesArray = getValue(node).replaceAll(" ", "").split(","); + if (codesArray.length > 0) { + int[] parsedCodesArray = new int[codesArray.length]; + for (int i = 0; i < codesArray.length; i++) { + parsedCodesArray[i] = Integer.parseInt(codesArray[i]); + } + add(RetransmissionRequiredResCodes, parsedCodesArray); + } + } + protected void addConcurrent(org.jdiameter.client.impl.helpers.Parameters name, Node node) { NodeList c = node.getChildNodes(); List items = new ArrayList(); @@ -417,15 +418,14 @@ protected void addStatisticLogger(org.jdiameter.client.impl.helpers.Parameters n String active_records; if (node.getAttributes().getNamedItem("active_records") != null) { active_records = node.getAttributes().getNamedItem("active_records").getNodeValue(); - } - else { + } else { active_records = (String) StatisticsActiveList.defValue(); } add(name, getInstance().add(StatisticsLoggerPause, Long.parseLong(pause)) - .add(StatisticsLoggerDelay, Long.parseLong(delay)) - .add(StatisticsEnabled, Boolean.parseBoolean(enabled)) - .add(StatisticsActiveList, active_records)); + .add(StatisticsLoggerDelay, Long.parseLong(delay)) + .add(StatisticsEnabled, Boolean.parseBoolean(enabled)) + .add(StatisticsActiveList, active_records)); } protected void addDictionary(org.jdiameter.client.impl.helpers.Parameters name, Node node) { @@ -437,19 +437,19 @@ protected void addDictionary(org.jdiameter.client.impl.helpers.Parameters name, dicConfiguration.add(DictionaryClass, clazz); } - param = node.getAttributes().getNamedItem("enabled"); + param = node.getAttributes().getNamedItem("enabled"); if (param != null) { String enabled = param.getNodeValue(); dicConfiguration.add(DictionaryEnabled, Boolean.valueOf(enabled)); } - param = node.getAttributes().getNamedItem("sendLevel"); + param = node.getAttributes().getNamedItem("sendLevel"); if (param != null) { String sendLevel = param.getNodeValue(); dicConfiguration.add(DictionarySendLevel, sendLevel); } - param = node.getAttributes().getNamedItem("receiveLevel"); + param = node.getAttributes().getNamedItem("receiveLevel"); if (param != null) { String receiveLevel = param.getNodeValue(); dicConfiguration.add(DictionaryReceiveLevel, receiveLevel); @@ -471,11 +471,9 @@ protected void addThreadPool(Node item) { int v = Integer.parseInt(n.getNodeValue()); if (n.getNodeName().equals("size")) { threadPoolConfiguration.add(ThreadPoolSize, v); - } - else if (n.getNodeName().equals("priority")) { + } else if (n.getNodeName().equals("priority")) { threadPoolConfiguration.add(ThreadPoolPriority, v); - } - else { + } else { //log.error("Unkonwn attribute on " + item.getNodeName() + ", attribute name: " + n.getNodeName()); } } @@ -502,9 +500,9 @@ protected void addSecurity(Node node) { protected Configuration addSecurityData(Node node) { AppConfiguration sd = getInstance().add(SDName, node.getAttributes().getNamedItem("name").getNodeValue()) - .add(SDProtocol, node.getAttributes().getNamedItem("protocol").getNodeValue()) - .add(SDEnableSessionCreation, Boolean.valueOf(node.getAttributes().getNamedItem("enable_session_creation").getNodeValue())) - .add(SDUseClientMode, Boolean.valueOf(node.getAttributes().getNamedItem("use_client_mode").getNodeValue())); + .add(SDProtocol, node.getAttributes().getNamedItem("protocol").getNodeValue()) + .add(SDEnableSessionCreation, Boolean.valueOf(node.getAttributes().getNamedItem("enable_session_creation").getNodeValue())) + .add(SDUseClientMode, Boolean.valueOf(node.getAttributes().getNamedItem("use_client_mode").getNodeValue())); NodeList c = node.getChildNodes(); @@ -516,15 +514,15 @@ protected Configuration addSecurityData(Node node) { } if (nodeName.equals("KeyData")) { sd.add(KeyData, getInstance().add(KDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) - .add(KDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) - .add(KDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) - .add(KDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); + .add(KDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) + .add(KDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) + .add(KDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } if (nodeName.equals("TrustData")) { sd.add(TrustData, getInstance().add(TDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) - .add(TDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) - .add(TDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) - .add(TDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); + .add(TDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) + .add(TDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) + .add(TDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } } return sd; @@ -536,8 +534,7 @@ protected void addNetwork(Node node) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Peers")) { addPeers(c.item(i)); - } - else if (nodeName.equals("Realms")) { + } else if (nodeName.equals("Realms")) { addRealms(c.item(i)); } } @@ -569,8 +566,8 @@ protected void addRealms(Node node) { protected Configuration addPeer(Node node) { AppConfiguration peerConfig = getInstance() - .add(PeerRating, new Integer(node.getAttributes().getNamedItem("rating").getNodeValue())) - .add(PeerName, node.getAttributes().getNamedItem("name").getNodeValue()); + .add(PeerRating, new Integer(node.getAttributes().getNamedItem("rating").getNodeValue())) + .add(PeerName, node.getAttributes().getNamedItem("name").getNodeValue()); if (node.getAttributes().getNamedItem("ip") != null) { peerConfig.add(PeerIp, node.getAttributes().getNamedItem("ip").getNodeValue()); } @@ -587,12 +584,12 @@ protected Configuration addPeer(Node node) { protected Configuration addRealm(Node node) { AppConfiguration realmEntry = getInstance(). - add(ApplicationId, new Configuration[] {addApplicationID(node.getChildNodes())}). - add(RealmName, getAttrValue(node, "name")). - add(RealmHosts, getAttrValue(node, "peers")). - add(RealmLocalAction, getAttrValue(node, "local_action")). - add(RealmEntryIsDynamic, Boolean.valueOf(getAttrValue(node, "dynamic"))). - add(RealmEntryExpTime, Long.valueOf(getAttrValue(node, "exp_time"))); + add(ApplicationId, new Configuration[]{addApplicationID(node.getChildNodes())}). + add(RealmName, getAttrValue(node, "name")). + add(RealmHosts, getAttrValue(node, "peers")). + add(RealmLocalAction, getAttrValue(node, "local_action")). + add(RealmEntryIsDynamic, Boolean.valueOf(getAttrValue(node, "dynamic"))). + add(RealmEntryExpTime, Long.valueOf(getAttrValue(node, "exp_time"))); NodeList childNodes = node.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { @@ -650,12 +647,10 @@ protected Configuration addApplicationID(Node node) { for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("VendorId")) { - e.add(VendorId, getLongValue(c.item(i))); - } - else if (nodeName.equals("AuthApplId")) { + e.add(VendorId, getLongValue(c.item(i))); + } else if (nodeName.equals("AuthApplId")) { e.add(AuthApplId, getLongValue(c.item(i))); - } - else if (nodeName.equals("AcctApplId")) { + } else if (nodeName.equals("AcctApplId")) { e.add(AcctApplId, getLongValue(c.item(i))); } } @@ -668,60 +663,43 @@ protected void addExtensions(Node node) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("MetaData")) { addInternalExtension(InternalMetaData, getValue(c.item(i))); - } - else if (nodeName.equals("MessageParser")) { + } else if (nodeName.equals("MessageParser")) { addInternalExtension(InternalMessageParser, getValue(c.item(i))); - } - else if (nodeName.equals("ElementParser")) { + } else if (nodeName.equals("ElementParser")) { addInternalExtension(InternalElementParser, getValue(c.item(i))); - } - else if (nodeName.equals("RouterEngine")) { + } else if (nodeName.equals("RouterEngine")) { addInternalExtension(InternalRouterEngine, getValue(c.item(i))); - } - else if (nodeName.equals("PeerController")) { + } else if (nodeName.equals("PeerController")) { addInternalExtension(InternalPeerController, getValue(c.item(i))); - } - else if (nodeName.equals("RealmController")) { + } else if (nodeName.equals("RealmController")) { addInternalExtension(InternalRealmController, getValue(c.item(i))); - } - else if (nodeName.equals("SessionFactory")) { + } else if (nodeName.equals("SessionFactory")) { addInternalExtension(InternalSessionFactory, getValue(c.item(i))); - } - else if (nodeName.equals("TransportFactory")) { + } else if (nodeName.equals("TransportFactory")) { addInternalExtension(InternalTransportFactory, getValue(c.item(i))); - } - else if (nodeName.equals("Connection")) { + } else if (nodeName.equals("Connection")) { addInternalExtension(InternalConnectionClass, getValue(c.item(i))); - } - else if (nodeName.equals("PeerFsmFactory")) { + } else if (nodeName.equals("PeerFsmFactory")) { addInternalExtension(InternalPeerFsmFactory, getValue(c.item(i))); - } - else if (nodeName.equals("StatisticFactory")) { + } else if (nodeName.equals("StatisticFactory")) { addInternalExtension(InternalStatisticFactory, getValue(c.item(i))); - } - else if (nodeName.equals("ConcurrentFactory")) { + } else if (nodeName.equals("ConcurrentFactory")) { addInternalExtension(InternalConcurrentFactory, getValue(c.item(i))); - } - else if (nodeName.equals("ConcurrentEntityFactory")) { + } else if (nodeName.equals("ConcurrentEntityFactory")) { addInternalExtension(InternalConcurrentEntityFactory, getValue(c.item(i))); - } - else if (nodeName.equals("SessionDatasource")) { + } else if (nodeName.equals("SessionDatasource")) { addInternalExtension(InternalSessionDatasource, getValue(c.item(i))); - } - else if (nodeName.equals("TimerFacility")) { + } else if (nodeName.equals("TimerFacility")) { addInternalExtension(InternalTimerFacility, getValue(c.item(i))); } //FIXME: possibly should not be in client... else if (nodeName.equals("AgentRedirect")) { addInternalExtension(InternalAgentRedirect, getValue(c.item(i))); - } - else if (nodeName.equals("AgentConfiguration")) { - add(InternalAgentConfiguration, getValue(c.item(i))) ; - } - else if (nodeName.equals("StatisticProcessor")) { - addInternalExtension(InternalStatisticProcessor, getValue(c.item(i))) ; - } - else { + } else if (nodeName.equals("AgentConfiguration")) { + add(InternalAgentConfiguration, getValue(c.item(i))); + } else if (nodeName.equals("StatisticProcessor")) { + addInternalExtension(InternalStatisticProcessor, getValue(c.item(i))); + } else { appendOtherExtension(c.item(i)); } } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java index da48e5617..39b1b7c59 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java @@ -87,6 +87,8 @@ public class MessageImpl implements IMessage { AvpSetImpl avpSet; boolean isNetworkRequest = false; + boolean isRetransSupervisionActive = false; + int numberOfRetransAllowed = Integer.MIN_VALUE; transient IPeer peer; transient TimerTask timerTask; @@ -265,6 +267,28 @@ public void setReTransmitted(boolean b) { } } + public boolean isRetransmissionSupervised() { + return this.isRetransSupervisionActive; + } + + public void setRetransmissionSupervised(boolean arg) { + this.isRetransSupervisionActive = arg; + } + + public boolean isRetransmissionAllowed() { + return this.numberOfRetransAllowed > 0; + } + + public void setNumberOfRetransAllowed(int arg) { + if(this.numberOfRetransAllowed < 0) { + this.numberOfRetransAllowed = arg; + } + } + + public void decrementNumberOfRetransAllowed() { + this.numberOfRetransAllowed--; + } + @Override public int getCommandCode() { return this.commandCode; diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java new file mode 100644 index 000000000..fc2743a70 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java @@ -0,0 +1,228 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + */ + +package org.jdiameter.client.impl.router; + +import org.jdiameter.api.Configuration; +import org.jdiameter.api.MetaData; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.client.api.IMessage; +import org.jdiameter.client.api.controller.IPeer; +import org.jdiameter.client.api.controller.IPeerTable; +import org.jdiameter.client.api.controller.IRealmTable; +import org.jdiameter.common.api.concurrent.IConcurrentFactory; +import org.jdiameter.common.api.data.IRoutingAwareSessionDatasource; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Extends capabilities of basic router implementation {@link RouterImpl} with extra features + * related to failure detection and failure aware routing. Rating of a particular peer is + * taken into consideration when deciding about an order of peers usage in case of failure + * detection. The highest rating peers are used first, then lower priorities peers next, etc. + * If several peers are marked with the same rating, load balancing algorithm is executed among + * them. In case of all higher priority peers failure, lower priority peers are considered. + * Afterwards, in case any higher priority peer becomes available again, only new sessions requests + * should be targeted again to higher priority peers, i.e. currently handled session stays + * assigned to a peer selected beforehand. + */ +public class FailureAwareRouter extends WeightedRoundRobinRouter { + + private static final Logger logger = LoggerFactory.getLogger(FailureAwareRouter.class); + + private IRoutingAwareSessionDatasource sessionDatasource = null; + + private int lastSelectedRating = -1; + + /** + * Parameterized constructor. Should be called by any subclasses. + */ + public FailureAwareRouter(IContainer container, IConcurrentFactory concurrentFactory, IRealmTable realmTable, Configuration config, MetaData aMetaData) { + super(container, concurrentFactory, realmTable, config, aMetaData); + + ISessionDatasource sds = container.getAssemblerFacility().getComponentInstance(ISessionDatasource.class); + if (sds instanceof IRoutingAwareSessionDatasource) { + this.sessionDatasource = (IRoutingAwareSessionDatasource) sds; + } + if(logger.isDebugEnabled()) { + logger.debug("Constructor for FailureAwareRouter (session persistent routing {})", isSessionPersistentRoutingEnabled() ? "enabled" : "disabled"); + } + } + + /** + * Narrows down the subset of peers selected by {@link RouterImpl} superclass to those with + * the highest rating only. + * + * @see org.jdiameter.client.impl.router.RouterImpl#getAvailablePeers(java.lang.String, java.lang.String[], org.jdiameter.client.api.controller.IPeerTable) + */ + @Override + protected List getAvailablePeers(String destRealm, String[] peers, IPeerTable manager) { + List selectedPeers = super.getAvailablePeers(destRealm, peers, manager); + + int maxRating = findMaximumRating(selectedPeers); + if (maxRating >= 0 && maxRating != lastSelectedRating) { + lastSelectedRating = maxRating; + resetRoundRobinContext(); + } + + selectedPeers = narrowToRatingBasedSubset(selectedPeers, maxRating); + if(logger.isDebugEnabled()) { + logger.debug("Final subset of peers with rating [{}]: {}", maxRating, selectedPeers); + } + + return selectedPeers; + } + + /** + * Applies load balancing algorithm and session persistence thereafter if its enabled. + * + * @see org.jdiameter.client.impl.router.RouterImpl#selectPeer(java.util.List, org.jdiameter.client.api.IMessage) + * @see org.jdiameter.common.impl.data.RoutingAwareDataSource + */ + @Override + public IPeer selectPeer(List availablePeers, IMessage message) { + IPeer peer = null; + String sessionAssignedPeer = null; + + if (isSessionPersistentRoutingEnabled()) { + sessionAssignedPeer = sessionDatasource.getSessionPeer(message.getSessionId()); + if (sessionAssignedPeer != null) { + if(logger.isDebugEnabled()) { + logger.debug("Sticky sessions are enabled and peer [{}] is assigned to the current session [{}]", + new Object[]{sessionAssignedPeer, message.getSessionId()}); + } + peer = findPeer(sessionAssignedPeer, availablePeers); + if (peer != null) { + return peer; + } + else { + if(logger.isDebugEnabled()) { + logger.debug("Peer [{}] assigned to session [{}] so far is not available anymore", sessionAssignedPeer, message.getSessionId()); + } + } + } else { + if(logger.isDebugEnabled()) { + logger.debug("Sticky sessions are enabled and no peer has been yet assigned to the current session [{}]", message.getSessionId()); + } + } + } + + if(logger.isDebugEnabled()) { + logger.debug(super.dumpRoundRobinContext()); + } + peer = super.selectPeer(availablePeers); + + if (isSessionPersistentRoutingEnabled()) { + if (sessionAssignedPeer != null) { + if(logger.isDebugEnabled()) { + logger.debug("Peer reselection took place from [{}] to [{}] on session [{}]", + new Object[]{sessionAssignedPeer, peer.getUri().getFQDN(), message.getSessionId()}); + } + sessionDatasource.setSessionPeer(message.getSessionId(), peer); + } + } + + return peer; + } + + /* + * (non-Javadoc) + * @see org.jdiameter.client.impl.router.RouterImpl#isSessionAware() + */ + @Override + public boolean isSessionAware() { + return isSessionPersistentRoutingEnabled(); + } + + /* + * (non-Javadoc) + * @see org.jdiameter.client.impl.router.RouterImpl#getLastSelectedRating() + */ + @Override + protected int getLastSelectedRating() { + return this.lastSelectedRating; + } + + /* + * (non-Javadoc) + * @see org.jdiameter.client.impl.router.RouterImpl#isWrapperFor(java.lang.Class) + */ + @Override + public boolean isWrapperFor(Class aClass) { + if (aClass == IRoutingAwareSessionDatasource.class) { + return isSessionAware(); + } + else { + return super.isWrapperFor(aClass); + } + } + + /* + * (non-Javadoc) + * @see org.jdiameter.client.impl.router.RouterImpl#unwrap(java.lang.Class) + */ + @Override + public T unwrap(Class aClass) { + if (aClass == IRoutingAwareSessionDatasource.class) { + return aClass.cast(sessionDatasource); + } + else { + return super.unwrap(aClass); + } + } + + /*********************************************************************** + * *********************** Local helper methods ************************* + ***********************************************************************/ + + private List narrowToRatingBasedSubset(List peers, int rating) { + List peersSubset = new ArrayList(5); + for (IPeer peer : peers) { + if (peer.getRating() == rating) { + peersSubset.add(peer); + } + } + return peersSubset; + } + + private int findMaximumRating(List peers) { + int maxRating = -1; + for (IPeer peer : peers) { + maxRating = Math.max(maxRating, peer.getRating()); + } + return maxRating; + } + + private IPeer findPeer(String fqdn, List peers) { + for (IPeer peer : peers) { + if (peer.getUri().getFQDN().equals(fqdn)) { + return peer; + } + } + return null; + } + + private boolean isSessionPersistentRoutingEnabled() { + return this.sessionDatasource != null; + } +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java index 09d4cfee1..9b250c19c 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java @@ -1,78 +1,47 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, TeleStax Inc. and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.client.impl.router; -import static org.jdiameter.client.impl.helpers.Parameters.AcctApplId; -import static org.jdiameter.client.impl.helpers.Parameters.Agent; -import static org.jdiameter.client.impl.helpers.Parameters.ApplicationId; -import static org.jdiameter.client.impl.helpers.Parameters.AuthApplId; -import static org.jdiameter.client.impl.helpers.Parameters.OwnRealm; -import static org.jdiameter.client.impl.helpers.Parameters.RealmEntry; -import static org.jdiameter.client.impl.helpers.Parameters.RealmTable; -import static org.jdiameter.client.impl.helpers.Parameters.VendorId; -import static org.jdiameter.server.impl.helpers.Parameters.RealmEntryExpTime; -import static org.jdiameter.server.impl.helpers.Parameters.RealmEntryIsDynamic; -import static org.jdiameter.server.impl.helpers.Parameters.RealmHosts; -import static org.jdiameter.server.impl.helpers.Parameters.RealmLocalAction; -import static org.jdiameter.server.impl.helpers.Parameters.RealmName; -import static org.jdiameter.server.impl.helpers.Parameters.RequestTable; -import static org.jdiameter.server.impl.helpers.Parameters.RequestTableClearSize; -import static org.jdiameter.server.impl.helpers.Parameters.RequestTableSize; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.UnknownServiceException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -//PCB added for thread safe -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; @@ -83,6 +52,7 @@ import org.jdiameter.api.LocalAction; import org.jdiameter.api.Message; import org.jdiameter.api.MetaData; +import org.jdiameter.api.NoMorePeersAvailableException; import org.jdiameter.api.PeerState; import org.jdiameter.api.RouteException; import org.jdiameter.api.URI; @@ -103,6 +73,38 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.UnknownServiceException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import static org.jdiameter.client.impl.helpers.Parameters.AcctApplId; +import static org.jdiameter.client.impl.helpers.Parameters.Agent; +import static org.jdiameter.client.impl.helpers.Parameters.ApplicationId; +import static org.jdiameter.client.impl.helpers.Parameters.AuthApplId; +import static org.jdiameter.client.impl.helpers.Parameters.OwnRealm; +import static org.jdiameter.client.impl.helpers.Parameters.RealmEntry; +import static org.jdiameter.client.impl.helpers.Parameters.RealmTable; +import static org.jdiameter.client.impl.helpers.Parameters.VendorId; +import static org.jdiameter.server.impl.helpers.Parameters.RealmEntryExpTime; +import static org.jdiameter.server.impl.helpers.Parameters.RealmEntryIsDynamic; +import static org.jdiameter.server.impl.helpers.Parameters.RealmHosts; +import static org.jdiameter.server.impl.helpers.Parameters.RealmLocalAction; +import static org.jdiameter.server.impl.helpers.Parameters.RealmName; +import static org.jdiameter.server.impl.helpers.Parameters.RequestTable; +import static org.jdiameter.server.impl.helpers.Parameters.RequestTableClearSize; +import static org.jdiameter.server.impl.helpers.Parameters.RequestTableSize; + +//PCB added for thread safe + /** * Diameter Routing Core * @@ -159,17 +161,15 @@ protected void loadConfiguration(Configuration config) { String localHost = config.getStringValue(Parameters.OwnDiameterURI.ordinal(), null); try { this.realmTable.addLocalRealm(localRealm, new URI(localHost).getFQDN()); - } - catch (UnknownServiceException use) { + } catch (UnknownServiceException use) { throw new RuntimeException("Unable to create URI from Own URI config value:" + localHost, use); - } - catch (URISyntaxException use) { + } catch (URISyntaxException use) { throw new RuntimeException("Unable to create URI from Own URI config value:" + localHost, use); } if (config.getChildren(RequestTable.ordinal()) != null) { AppConfiguration requestTableConfig = (AppConfiguration) config.getChildren(org.jdiameter.server.impl.helpers.Parameters.RequestTable.ordinal())[0]; - int tSize = requestTableConfig.getIntValue(RequestTableSize.ordinal(),(Integer) RequestTableSize.defValue()); - int tClearSize = requestTableConfig.getIntValue(RequestTableClearSize.ordinal(),(Integer) RequestTableClearSize.defValue()); + int tSize = requestTableConfig.getIntValue(RequestTableSize.ordinal(), (Integer) RequestTableSize.defValue()); + int tClearSize = requestTableConfig.getIntValue(RequestTableClearSize.ordinal(), (Integer) RequestTableClearSize.defValue()); if (tSize > 0 && tClearSize >= tSize) { logger.warn("Configuration entry RequestTable, attribute 'clear_size' [{}] should not be greater than 'size' [{}]. Adjusting.", tSize, tClearSize); while (tClearSize >= tSize) { @@ -204,13 +204,12 @@ protected void loadConfiguration(Configuration config) { long acc = a.getLongValue(AcctApplId.ordinal(), 0); if (auth != 0) { appId = org.jdiameter.api.ApplicationId.createByAuthAppId(vnd, auth); - } - else { + } else { appId = org.jdiameter.api.ApplicationId.createByAccAppId(vnd, acc); } if (logger.isDebugEnabled()) { logger.debug("Realm [{}] has application Acct [{}] Auth [{}] Vendor [{}]", - new Object[]{name, appId.getAcctAppId(), appId.getAuthAppId(), appId.getVendorId()}); + new Object[]{name, appId.getAcctAppId(), appId.getAuthAppId(), appId.getVendorId()}); } break; } @@ -234,8 +233,7 @@ protected void loadConfiguration(Configuration config) { } } this.realmTable.addRealm(name, appId, locAction, agentConfImpl, isDynamic, expirationTime, hosts); - } - catch (Exception e) { + } catch (Exception e) { logger.warn("Unable to append realm entry", e); } } @@ -258,7 +256,7 @@ public void registerRequestRouteInfo(IRequest request) { Avp hostAvp = request.getAvps().getAvp(Avp.ORIGIN_HOST); Avp realmAvp = request.getAvps().getAvp(Avp.ORIGIN_REALM); AnswerEntry entry = new AnswerEntry(hopByHopId, hostAvp != null ? hostAvp.getDiameterIdentity() : null, - realmAvp != null ? realmAvp.getDiameterIdentity() : null); + realmAvp != null ? realmAvp.getDiameterIdentity() : null); int s = requestEntryMap.size(); // PCB added logging @@ -283,11 +281,9 @@ public void registerRequestRouteInfo(IRequest request) { logger.warn("RequestRoute map size is now [{}] after sleeping. Clearing it!", requestEntryMap.size()); requestEntryMap.clear(); } - } - catch (Exception e) { + } catch (Exception e) { logger.warn("Failure trying to clear RequestRoute map", e); - } - finally { + } finally { requestEntryTableLock.unlock(); } } @@ -296,11 +292,9 @@ public void registerRequestRouteInfo(IRequest request) { logger.debug("Adding request key [{}] to RequestRoute map for routing answers back to the requesting peer", messageKey); requestEntryMap.put(messageKey, entry); // requestSortedEntryTable.add(hopByHopId); - } - catch (Exception e) { + } catch (Exception e) { logger.warn("Unable to store route info", e); - } - finally { + } finally { // requestEntryTableLock.writeLock().unlock(); } } @@ -309,7 +303,7 @@ public void registerRequestRouteInfo(IRequest request) { private String makeRoutingKey(Message message) { String sessionId = message.getSessionId(); return new StringBuilder(sessionId != null ? sessionId : "null").append(message.getEndToEndIdentifier()) - .append(message.getHopByHopIdentifier()).toString(); + .append(message.getHopByHopIdentifier()).toString(); } @Override @@ -325,9 +319,8 @@ public String[] getRequestRouteInfo(IMessage message) { if (logger.isDebugEnabled()) { logger.debug("getRequestRouteInfo found host [{}] and realm [{}] for Message key Id [{}]", new Object[]{ans.getHost(), ans.getRealm(), messageKey}); } - return new String[] {ans.getHost(), ans.getRealm()}; - } - else { + return new String[]{ans.getHost(), ans.getRealm()}; + } else { if (logger.isWarnEnabled()) { logger.warn("Could not find route info for message key [{}]. Table size is [{}]", messageKey, requestEntryMap.size()); } @@ -368,12 +361,11 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException destHost = avpHost.getDiameterIdentity(); } if (logger.isDebugEnabled()) { - logger.debug("Looking up peer for request: [{}], DestHost=[{}], DestRealm=[{}]", new Object[] {message, destHost, destRealm}); + logger.debug("Looking up peer for request: [{}], DestHost=[{}], DestRealm=[{}]", new Object[]{message, destHost, destRealm}); } matchedRealm = (IRealm) this.realmTable.matchRealm(message); - } - else { + } else { //answer, search info = getRequestRouteInfo(message); if (info != null) { @@ -383,14 +375,13 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException if (destRealm == null) { logger.warn("Destination-Realm was null for hopbyhop id " + message.getHopByHopIdentifier()); } - } - else { + } else { logger.debug("No Host and realm found based on hopbyhop id of the answer associated request"); } //FIXME: if no info, should not send it ? //FIXME: add strict deff in route back table so stack does not have to lookup? if (logger.isDebugEnabled()) { - logger.debug("Looking up peer for answer: [{}], DestHost=[{}], DestRealm=[{}]", new Object[] {message, destHost, destRealm}); + logger.debug("Looking up peer for answer: [{}], DestHost=[{}], DestRealm=[{}]", new Object[]{message, destHost, destRealm}); } matchedRealm = (IRealm) this.realmTable.matchRealm(message, destRealm); } @@ -427,51 +418,32 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException logger.debug("Found a peer using destination host avp [{}] peer is [{}] with a valid connection.", destHost, c); //here matchedRealm MAY return c; - } - else { + } else { logger.debug("Finding peer by destination host avp [host={}] did not find anything. Now going to try finding one by destination realm [{}]", - destHost, destRealm); + destHost, destRealm); String[] peers = matchedRealm.getPeerNames(); if (peers == null || peers.length == 0) { throw new RouteException("Unable to find context by route information [" + destRealm + " ," + destHost + "]"); } - // Collect peers - ArrayList availablePeers = new ArrayList(5); - logger.debug("Looping through peers in realm [{}]", destRealm); - for (String peerName : peers) { - IPeer localPeer = manager.getPeer(peerName); - if (logger.isDebugEnabled()) { - logger.debug("Checking peer [{}] for name [{}]", new Object[]{localPeer, peerName}); - } - // ammendonca: added peer state check.. should not be needed but - // hasValidConnection is returning true for disconnected peers in *FTFlowTests - if (localPeer != null && localPeer.getState(PeerState.class) == PeerState.OKAY) { - if (localPeer.hasValidConnection()) { - if (logger.isDebugEnabled()) { - logger.debug("Found available peer to add to available peer list with uri [{}] with a valid connection", localPeer.getUri().toString()); - } - availablePeers.add(localPeer); - } - else { - if (logger.isDebugEnabled()) { - logger.debug("Found a peer with uri [{}] with no valid connection", localPeer.getUri()); - } - } - } + List availablePeers = getAvailablePeers(destRealm, peers, manager); + + if (message.isRetransmissionSupervised()) { + message.setNumberOfRetransAllowed(availablePeers.size() - 1); } if (logger.isDebugEnabled()) { - logger.debug("Performing Realm routing. Realm [{}] has the following peers available [{}] from list [{}]", - new Object[] {destRealm, availablePeers, Arrays.asList(peers)}); + logger.debug("Performing Realm routing. Realm [{}] has the following peers available {} from list {}", + new Object[]{destRealm, availablePeers, Arrays.asList(peers)}); } // Balancing - IPeer peer = selectPeer(availablePeers); + IPeer peer = selectPeer(availablePeers, message); if (peer == null) { - throw new RouteException("Unable to find valid connection to peer[" + destHost + "] in realm[" + destRealm + "]"); - } - else { + throw new NoMorePeersAvailableException( + "Unable to find a valid connection within realm [" + destRealm + "]", + isSessionAware(), dumpRoundRobinContext(), getLastSelectedRating()); + } else { if (logger.isDebugEnabled()) { logger.debug("Load balancing selected peer with uri [{}]", peer.getUri()); } @@ -481,6 +453,44 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException } } + protected List getAvailablePeers(String destRealm, String[] peers, IPeerTable manager) { + return getPeers(destRealm, peers, manager, PeerState.OKAY); + } + + private List getPeers(String destRealm, String[] peers, IPeerTable manager, PeerState state) { + List availablePeers = new ArrayList(5); + if (logger.isDebugEnabled()) { + logger.debug("Looping through peers in realm [{}]", destRealm); + } + for (String peerName : peers) { + IPeer localPeer = (IPeer) manager.getPeer(peerName); + if (logger.isDebugEnabled()) { + logger.debug("Checking peer [{}] for name [{}]", new Object[]{localPeer, peerName}); + } + + if (localPeer != null && localPeer.getState(PeerState.class) == state) { + if (localPeer.hasValidConnection()) { + if (logger.isDebugEnabled()) { + logger.debug( + "Found available peer to add to available peer list with uri [{}] with a valid connection", + localPeer.getUri().toString()); + } + availablePeers.add(localPeer); + } else { + if (logger.isDebugEnabled()) { + logger.debug("Found a peer with uri [{}] with no valid connection", localPeer.getUri()); + } + } + } + } + + return availablePeers; + } + + public boolean isSessionAware() { + return false; + } + @Override public IRealmTable getRealmTable() { return this.realmTable; @@ -501,7 +511,7 @@ public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable t int i = 0; // loop detected for (Avp avp : avps) { - String r = avp.getDiameterIdentity(); + String r = avp.getDiameterIdentity(); if (r.equals(metaData.getLocalPeer().getUri().getFQDN())) { throw new RouteException("Loop detected"); } @@ -558,8 +568,7 @@ public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable t //yes, possible that this will trigger this procedure twice, but thats worst than locking always. redirectTableLock.writeLock().lock(); trimRedirectTable(); - } - finally { + } finally { redirectTableLock.writeLock().unlock(); } } @@ -569,16 +578,14 @@ public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable t //redirectProcessing(answer, destRealm.getOctetString(), destHost !=null ? destHost.getOctetString():null); //we dont have to elect? updateRoute(request, e.getRedirectHost()); - } - else { + } else { if (redirectHosts != null && redirectHosts.length > 0) { String destHost = redirectHosts[0]; //setRouteInfo(answer, getRealmForPeer(destHost), destHost); updateRoute(request, destHost); } } - } - else { + } else { if (redirectHosts != null && redirectHosts.length > 0) { String destHost = redirectHosts[0]; //setRouteInfo(answer, getRealmForPeer(destHost), destHost); @@ -587,14 +594,11 @@ public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable t } //now send table.sendMessage((IMessage) request); - } - catch (AvpDataException exc) { + } catch (AvpDataException exc) { throw new InternalException(exc); - } - catch (IllegalDiameterStateException e) { + } catch (IllegalDiameterStateException e) { throw new InternalException(e); - } - catch (IOException e) { + } catch (IOException e) { throw new InternalException(e); } } @@ -609,8 +613,7 @@ private void trimRedirectTable() { redirectTable.remove(index); index--; //a trick :) } - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Error in redirect task cleanup.", e); break; } @@ -624,7 +627,7 @@ private void trimRedirectTable() { private void updateRoute(IRequest request, String destHost) { // Realm does not change I think... :) request.getAvps().removeAvp(Avp.DESTINATION_HOST); - request.getAvps().addAvp(Avp.DESTINATION_HOST, destHost, true, false, true); + request.getAvps().addAvp(Avp.DESTINATION_HOST, destHost, true, false, true); } @Override @@ -667,7 +670,7 @@ public boolean updateRoute(IRequest message) throws RouteException, AvpDataExcep break; case REALM_AND_APPLICATION: // Usage type: REALM AND APPLICATION matchedEntry = destRealm != null & appId != null & e.primaryKey != null & e.secondaryKey != null & destRealm.equals(e.primaryKey) - & appId.equals(e.secondaryKey); + & appId.equals(e.secondaryKey); break; case ALL_APPLICATION: // Usage type: ALL APPLICATION matchedEntry = appId != null & e.secondaryKey != null & appId.equals(e.secondaryKey); @@ -685,12 +688,11 @@ public boolean updateRoute(IRequest message) throws RouteException, AvpDataExcep //String newDestRealm = getRealmForPeer(destHost); //setRouteInfo(message, destRealm, newDestHost); updateRoute(message, newDestHost); - logger.debug("Redirect message from host={}; to new-host={}, realm={} ", new Object[] { destHost, newDestHost, destRealm}); + logger.debug("Redirect message from host={}; to new-host={}, realm={} ", new Object[]{destHost, newDestHost, destRealm}); return true; } } - } - finally { + } finally { redirectTableLock.readLock().unlock(); } return false; @@ -736,8 +738,7 @@ public void destroy() { if (!isStopped) { stop(); } - } - catch (Exception exc) { + } catch (Exception exc) { logger.error("Unable to stop router", exc); } @@ -747,6 +748,10 @@ public void destroy() { requestEntryMap = null; } + protected IPeer selectPeer(List availablePeers, IMessage message) { + return selectPeer(availablePeers); + } + protected IPeer selectPeer(List availablePeers) { IPeer p = null; for (IPeer c : availablePeers) { @@ -892,10 +897,9 @@ public boolean equals(Object other) { if (other instanceof RedirectEntry) { RedirectEntry that = (RedirectEntry) other; return liveTime == that.liveTime && usageType == that.usageType && - Arrays.equals(hosts, that.hosts) && !(primaryKey != null ? !primaryKey.equals(that.primaryKey) : that.primaryKey != null) && - !(secondaryKey != null ? !secondaryKey.equals(that.secondaryKey) : that.secondaryKey != null); - } - else { + Arrays.equals(hosts, that.hosts) && !(primaryKey != null ? !primaryKey.equals(that.primaryKey) : that.primaryKey != null) && + !(secondaryKey != null ? !secondaryKey.equals(that.secondaryKey) : that.secondaryKey != null); + } else { return false; } } @@ -955,4 +959,27 @@ public String toString() { return "AnswerEntry {" + "createTime=" + createTime + ", hopByHopId=" + hopByHopId + '}'; } } + + protected String dumpRoundRobinContext() { + return "Load balancing is not supported"; + } + + protected int getLastSelectedRating() { + return Integer.MIN_VALUE; + } + + @Override + public boolean isWrapperFor(Class aClass) { + return aClass == IRouter.class; + } + + @Override + public T unwrap(Class aClass) { + if (aClass == IRouter.class) { + return aClass.cast(this); + } + else { + return null; + } + } } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/WeightedRoundRobinRouter.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/WeightedRoundRobinRouter.java index b52a898a0..d686fb159 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/WeightedRoundRobinRouter.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/WeightedRoundRobinRouter.java @@ -32,8 +32,8 @@ /** * Weighted round-robin router implementation * - * @see http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling * @author Nils Sowen + * @see http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling */ public class WeightedRoundRobinRouter extends RouterImpl { @@ -52,7 +52,7 @@ public WeightedRoundRobinRouter(IContainer container, IConcurrentFactory concurr /** * Select peer by weighted round-robin scheduling * As documented in http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling - * + *

      *

      * The weighted round-robin scheduling is designed to better handle servers * with different processing capacities. Each server can be assigned a weight, @@ -106,7 +106,7 @@ public WeightedRoundRobinRouter(IContainer container, IConcurrentFactory concurr *

      * This method is internally synchronized due to concurrent modifications to lastSelectedPeer and currentWeight. * Please consider this when relying on heavy throughput. - * + *

      * Please note: if the list of availablePeers changes between calls (e.g. if a peer becomes active or inactive), * the balancing algorithm is disturbed and might be distributed uneven. * This is likely to happen if peers are flapping. @@ -138,7 +138,7 @@ public IPeer selectPeer(List availablePeers) { // Find best matching candidate. Synchronized here due to consistent changes on member variables synchronized (this) { - for ( ;; ) { + for (; ; ) { lastSelectedPeer = (lastSelectedPeer + 1) % peerSize; if (lastSelectedPeer == 0) { currentWeight = currentWeight - gcd; @@ -159,7 +159,7 @@ public IPeer selectPeer(List availablePeers) { } /** - * Return greatest common divisor for two integers + * Returns greatest common divisor for two integers * https://en.wikipedia.org/wiki/Greatest_common_divisor#Using_Euclid.27s_algorithm * * @param a @@ -169,4 +169,24 @@ public IPeer selectPeer(List availablePeers) { protected int gcd(int a, int b) { return (b == 0) ? a : gcd(b, a % b); } + + /** + * Resets all round-robin counters/variables in order to make the whole algorithm + * start from scratch. + */ + protected synchronized void resetRoundRobinContext() { + lastSelectedPeer = -1; + currentWeight = 0; + } + + /** + * Gets a readable format of the current round-robin context, i.e. last selected + * peer and current weight + * + * @return readable summary of round-robin context + */ + @Override + protected String dumpRoundRobinContext() { + return String.format("Current round-robin context is: lastSelectedPeer=[%d] currentWeight=[%d]", lastSelectedPeer, currentWeight); + } } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/TCPClientConnection.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/TCPClientConnection.java index 10521c373..8e6a98331 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/TCPClientConnection.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/TCPClientConnection.java @@ -387,6 +387,15 @@ protected boolean processBufferedMessages(Event event) throws AvpDataException { } } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("TCPClientConnection [createdTime=").append(createdTime) + .append(", cachedKey=").append(cachedKey).append(", isConnected=") + .append(isConnected()).append("]"); + return builder.toString(); + } + //------------------ helper classes ------------------------ private enum EventType { CONNECTED, DISCONNECTED, MESSAGE_RECEIVED, DATA_EXCEPTION diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java new file mode 100644 index 000000000..f130f8952 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java @@ -0,0 +1,58 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2010, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jdiameter.common.api.data; + +import org.jdiameter.api.SessionPersistenceStorage; +import org.jdiameter.client.api.controller.IPeer; + +/** + * Extends basic session storage with capabilities of CRUD operations + * for session persistence records which bind sessions with peers that + * are processing those sessions. + */ +public interface IRoutingAwareSessionDatasource extends ISessionDatasource, SessionPersistenceStorage { + + /** + * Gets a name of the peer that is currently assigned to a given session. + * + * @param sessionId session identifier used as mapping key in session storage + * @return peer name + */ + String getSessionPeer(String sessionId); + + /** + * Binds a particular session with a given peer. + * + * @param sessionId session identifier used as mapping key in session storage + * @param peer object to bind + */ + void setSessionPeer(String sessionId, IPeer peer); + + /** + * Unbinds a particular session from a given peer. + * + * @param sessionId session identifier used as mapping key in session storage + * @return peer name that has just been unbound + */ + String removeSessionPeer(String sessionId); +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java new file mode 100644 index 000000000..61230bb5a --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java @@ -0,0 +1,165 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2006, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jdiameter.common.impl.app; + +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.client.api.IMessage; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.client.api.controller.IPeer; +import org.jdiameter.client.api.controller.IPeerTable; +import org.jdiameter.common.api.app.IAppSessionData; +import org.jdiameter.common.api.data.IRoutingAwareSessionDatasource; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; + +import static org.jdiameter.client.impl.helpers.Parameters.SessionInactivityTimeOut; + +/** + * Routing aware extension of {@link AppSessionImpl} that enables proper diameter session + * load balancing. It provides diameter session persistence which maps a single diameter + * session to a single peer which is processing the session. + */ +public abstract class AppRoutingAwareSessionImpl extends AppSessionImpl { + + private static final String SESSION_INACTIVITY_TIMER_NAME = "Ro_CLIENT_SESSION_INACTIVITY_TIMER"; + + private static final Logger logger = LoggerFactory.getLogger(AppRoutingAwareSessionImpl.class); + + private transient IPeerTable peerTable = null; + private transient IRoutingAwareSessionDatasource sessionPersistenceStorage = null; + + private final int sesInactivityTimerVal; + private Serializable sesInactivityTimerId = null; + + /** + * Parameterized constructor. If session persistence is supposed to be enabled, sessionStorage + * argument should be of type {@link org.jdiameter.common.impl.data.RoutingAwareDataSource}. + * + * @param sessionStorage session datasource + * @param sessionFactory session factory + * @param appSessionData session data + */ + public AppRoutingAwareSessionImpl(ISessionDatasource sessionStorage, ISessionFactory sessionFactory, IAppSessionData appSessionData) { + super(sessionFactory, appSessionData); + peerTable = sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(IPeerTable.class); + sesInactivityTimerVal = sessionFactory.getContainer().getConfiguration().getIntValue(SessionInactivityTimeOut.ordinal(), + (Integer) SessionInactivityTimeOut.defValue()) * 1000; + if (sessionStorage instanceof IRoutingAwareSessionDatasource) { + sessionPersistenceStorage = (IRoutingAwareSessionDatasource) sessionStorage; + } + } + + /** + * Tells whether session persistent routing is enabled for this session. + * + * @return true if enabled + */ + protected boolean isSessionPersistenceEnabled() { + return this.sessionPersistenceStorage != null; + } + + /** + * Initiates session persistence record, i.e. assigns the current session to a peer which is + * processing it. Session persistence record shall be created after a peer had answered the + * first (initial) request for that session. + * + * @param reqEvent request that had been sent beforehand + * @param ansEvent response that has been just received + */ + protected void initSessionPersistenceContext(AppEvent reqEvent, AppEvent ansEvent) { + try { + IPeer peer = null; + if (reqEvent.getMessage() instanceof IMessage) { + peer = ((IMessage) reqEvent.getMessage()).getPeer(); + } + else { + logger.warn("Cannot retrieve message detailed context for session [{}]", this.getSessionId()); + } + + if (peer == null) { + logger.warn("Taking peer from AVP as no peer is assigned yet to the following message in session [{}]: [{}]", + this.getSessionId(), reqEvent.getMessage().getAvps()); + peer = peerTable.getPeer(ansEvent.getOriginHost()); + } + + sessionPersistenceStorage.setSessionPeer(this.getSessionId(), peer); + logger.debug("Session persistent routing will be enforced for session [{}] with peer [{}]", this.getSessionId(), peer); + + } catch (Exception ex) { + logger.error("Cannot update session persistence data, default routing will be applied", ex); + } + } + + /** + * Removes mapping between current session and the peer that has been assigned so far. + * + * @return peer name that has been assigned so far + */ + protected String flushSessionPersistenceContext() { + try { + return sessionPersistenceStorage.removeSessionPeer(this.getSessionId()); + } catch (Exception ex) { + logger.error("Cannot update session persistence data", ex); + return null; + } + } + + /** + * Starts maximum session inactivity timer which defines how much time the persistence record + * should be kept if there is no request sent within a session. + */ + protected void startSessionInactivityTimer() { + logger.debug("Scheduling session inactivity timer equal to [{}] ms", sesInactivityTimerVal); + stopSessionInactivityTimer(); + this.sesInactivityTimerId = this.timerFacility.schedule(this.getSessionId(), SESSION_INACTIVITY_TIMER_NAME, sesInactivityTimerVal); + } + + /** + * Stops session inactivity timer. + */ + protected void stopSessionInactivityTimer() { + if (this.sesInactivityTimerId != null) { + logger.debug("Stopping session inactivity timer [{}]", this.sesInactivityTimerId); + timerFacility.cancel(this.sesInactivityTimerId); + this.sesInactivityTimerId = null; + } + } + + /** + * Handles expiry of session inactivity timer. Should be called by any subclasses which define + * any additional timers. + * + * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) + */ + @Override + public void onTimer(String timerName) { + if (timerName.equals(SESSION_INACTIVITY_TIMER_NAME)) { + //no need to interfere with session state machine (simply remove routing context used for sticky sessions based routing) + String oldPeer = flushSessionPersistenceContext(); + logger.debug("Session inactivity timer expired so routing context for peer [{}] was removed from session [{}]", oldPeer, this.getSessionId()); + } + } +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/AppCCASessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/AppCCASessionImpl.java index 83919a918..d7a0e1123 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/AppCCASessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/AppCCASessionImpl.java @@ -52,14 +52,15 @@ import org.jdiameter.api.cca.CCASession; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionData; -import org.jdiameter.common.impl.app.AppSessionImpl; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.jdiameter.common.impl.app.AppRoutingAwareSessionImpl; /** * * @author Bartosz Baranowski * @author Alexandre Mendonca */ -public abstract class AppCCASessionImpl extends AppSessionImpl implements CCASession, NetworkReqListener { +public abstract class AppCCASessionImpl extends AppRoutingAwareSessionImpl implements CCASession,NetworkReqListener { protected Lock sendAndStateLock = new ReentrantLock(); @@ -68,8 +69,8 @@ public abstract class AppCCASessionImpl extends AppSessionImpl implements CCASes //FIXME: use FastList ? protected List stateListeners = new CopyOnWriteArrayList(); - public AppCCASessionImpl(ISessionFactory sf, IAppSessionData data) { - super(sf, data); + public AppCCASessionImpl(ISessionDatasource sessionStorage, ISessionFactory sf, IAppSessionData data) { + super(sessionStorage, sf, data); } @Override diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/CCASessionFactoryImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/CCASessionFactoryImpl.java index d8bf0d2f7..16d575126 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/CCASessionFactoryImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/CCASessionFactoryImpl.java @@ -278,7 +278,7 @@ public AppSession getSession(String sessionId, Class aClas ClientCCASessionImpl clientSession = null; IClientCCASessionData data = (IClientCCASessionData) this.sessionDataFactory.getAppSessionData(ClientCCASession.class, sessionId); - clientSession = new ClientCCASessionImpl(data, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), + clientSession = new ClientCCASessionImpl(data, this.getMessageFactory(), iss, sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; @@ -320,8 +320,8 @@ public AppSession getNewSession(String sessionId, Class aC } IClientCCASessionData data = (IClientCCASessionData) this.sessionDataFactory.getAppSessionData(ClientCCASession.class, sessionId); data.setApplicationId(applicationId); - clientSession = new ClientCCASessionImpl(data, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), - this.getClientContextListener(), this.getStateListener()); + clientSession = new ClientCCASessionImpl(data, this.getMessageFactory(), iss, sessionFactory, + this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/AppRoSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/AppRoSessionImpl.java index cff2a7435..729c057b9 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/AppRoSessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/AppRoSessionImpl.java @@ -52,14 +52,15 @@ import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.ro.IRoSessionData; -import org.jdiameter.common.impl.app.AppSessionImpl; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.jdiameter.common.impl.app.AppRoutingAwareSessionImpl; /** * * @author Bartosz Baranowski * @author Alexandre Mendonca */ -public abstract class AppRoSessionImpl extends AppSessionImpl implements NetworkReqListener, StateMachine { +public abstract class AppRoSessionImpl extends AppRoutingAwareSessionImpl implements NetworkReqListener, StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); @@ -67,8 +68,8 @@ public abstract class AppRoSessionImpl extends AppSessionImpl implements Network //FIXME: change this to single ref! protected transient List stateListeners = new CopyOnWriteArrayList(); - public AppRoSessionImpl(ISessionFactory sf, IRoSessionData sessionData) { - super(sf, sessionData); + public AppRoSessionImpl(ISessionDatasource sessionStorage, ISessionFactory sf, IRoSessionData sessionData) { + super(sessionStorage, sf, sessionData); } @Override diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java index e139b07ff..747c382a4 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java @@ -19,13 +19,13 @@ package org.jdiameter.common.impl.app.ro; -import java.util.concurrent.ScheduledFuture; - import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; +import org.jdiameter.api.Peer; import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; @@ -56,6 +56,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.ScheduledFuture; + /** * Default Diameter Ro Session Factory implementation * @@ -270,8 +272,8 @@ public AppSession getNewSession(String sessionId, Class aC IClientRoSessionData sessionData = (IClientRoSessionData) this.sessionDataFactory.getAppSessionData(ClientRoSession.class, sessionId); sessionData.setApplicationId(applicationId); - clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), - this.getClientContextListener(), this.getStateListener()); + clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), iss, sessionFactory, + this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); @@ -320,8 +322,8 @@ public AppSession getSession(String sessionId, Class aClas try { if (aClass == ClientRoSession.class) { IClientRoSessionData sessionData = (IClientRoSessionData) this.sessionDataFactory.getAppSessionData(ClientRoSession.class, sessionId); - ClientRoSessionImpl clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), - this.getClientContextListener(), this.getStateListener()); + ClientRoSessionImpl clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), iss, sessionFactory, + this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; @@ -372,6 +374,13 @@ public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerE } + public void doRequestTimeout(ClientRoSession session, Message msg, Peer peer) throws InternalException { + + } + + public void doPeerUnavailability(RouteException cause, ClientRoSession session, Message msg, Peer peer) throws InternalException { + } + // Message Factory Methods -------------------------------------------------- @Override @@ -498,8 +507,7 @@ public void indicateServiceError(ClientRoSession clientRoSessionImpl) { @Override public void txTimerExpired(ClientRoSession session) { - // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); - session.release(); + // TODO Auto-generated method stub } @Override diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java index d066798e6..8a40cd84f 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java @@ -42,9 +42,6 @@ package org.jdiameter.common.impl.data; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; - import org.jdiameter.api.BaseSession; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.client.api.IContainer; @@ -77,6 +74,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + /** * Local implementation of session datasource for {@link ISessionDatasource} * @@ -89,7 +89,7 @@ public class LocalDataSource implements ISessionDatasource { protected HashMap, IAppSessionDataFactory> appSessionDataFactories = new HashMap, IAppSessionDataFactory>(); - private ConcurrentHashMap sessionIdToEntry = new ConcurrentHashMap(); + protected ConcurrentHashMap sessionIdToEntry = new ConcurrentHashMap(); private static final Logger logger = LoggerFactory.getLogger(LocalDataSource.class); @@ -152,23 +152,34 @@ public NetworkReqListener removeSessionListener(String sessionId) { @Override public void addSession(BaseSession session) { - logger.debug("addSession({})", session); - SessionEntry se = null; + addSession(session, SessionEntry.class); + } + + protected void addSession(BaseSession session, Class sessionWraperType) { + logger.debug("addSession({}) => {}", session.getSessionId(), session); + T se = null; String sessionId = session.getSessionId(); //FIXME: check here replicable vs not replicable? if (this.sessionIdToEntry.containsKey(sessionId)) { - se = this.sessionIdToEntry.get(sessionId); - if ( !(se.session instanceof ISession) || se.session.isReplicable()) { //must be not replicable so we can "overwrite" - throw new IllegalArgumentException("Sessin with id: " + sessionId + ", already exists!"); - } - else { - this.sessionIdToEntry.put(sessionId, se); + se = sessionWraperType.cast(this.sessionIdToEntry.get(sessionId)); + if( se != null && (!(se.session instanceof ISession) || se.session.isReplicable()) ) { //must be not replicable so we can "overwrite" + throw new IllegalArgumentException("Session with id: " + sessionId + ", already exists!"); } } - else { - se = new SessionEntry(); + + if(se == null) { + try { + se = sessionWraperType.newInstance(); + } catch (InstantiationException e) { + logger.warn("Cannot instantiate session object of type: " + sessionWraperType.getCanonicalName(), e); + throw new IllegalArgumentException("Cannot instantiate session object of type: " + sessionWraperType.getCanonicalName(), e); + } catch (IllegalAccessException e) { + logger.warn("Cannot instantiate session object of type: " + sessionWraperType.getCanonicalName(), e); + throw new IllegalArgumentException("Cannot instantiate session object of type: " + sessionWraperType.getCanonicalName(), e); + } } + se.session = session; this.sessionIdToEntry.put(session.getSessionId(), se); } @@ -217,7 +228,7 @@ public String toString() { } //simple class to reduce collections overhead. - private class SessionEntry { + protected static class SessionEntry { BaseSession session; NetworkReqListener listener; diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java new file mode 100644 index 000000000..2dc9cb863 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java @@ -0,0 +1,157 @@ +package org.jdiameter.common.impl.data; + +import org.jdiameter.api.BaseSession; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.client.api.controller.IPeer; +import org.jdiameter.common.api.data.IRoutingAwareSessionDatasource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Implementation of routing aware session datasource for {@link IRoutingAwareSessionDatasource}. + */ +public class RoutingAwareDataSource extends LocalDataSource implements IRoutingAwareSessionDatasource { + + private static final Logger logger = LoggerFactory.getLogger(RoutingAwareDataSource.class); + + + /** + * Default constructor. + */ + public RoutingAwareDataSource() { + super(); + logger.debug("Constructor for RoutingAwareDataSource: nothing to do"); + } + + /** + * Parameterized constructor. Should be called by any subclasses. + * + * @param container container object + */ + public RoutingAwareDataSource(IContainer container) { + super(container); + logger.debug("Constructor for RoutingAwareDataSource: nothing to do"); + } + + /* + * (non-Javadoc) + * @see org.jdiameter.common.impl.data.LocalDataSource#addSession(org.jdiameter.api.BaseSession) + */ + @Override + public void addSession(BaseSession session) { + addSession(session, RoutingAwareSessionEntry.class); + } + + /* + * (non-Javadoc) + * @see org.jdiameter.common.api.data.IRoutingAwareSessionDatasource#setSessionPeer(java.lang.String, org.jdiameter.client.api.controller.IPeer) + */ + @Override + public void setSessionPeer(String sessionId, IPeer peer) { + logger.debug("Assigning routing destination peer [{}] to session [{}]", peer, sessionId); + SessionEntry se = sessionIdToEntry.get(sessionId); + if (se == null) { + throw new IllegalArgumentException("No session entry for id: " + sessionId); + } + else if (!(se instanceof RoutingAwareSessionEntry)) { + throw new IllegalArgumentException("Session entry is of a wrong type for id: " + sessionId); + } + else { + ((RoutingAwareSessionEntry) se).peer = peer.getUri().getFQDN(); + } + } + + /* + * (non-Javadoc) + * @see org.jdiameter.common.api.data.IRoutingAwareSessionDatasource#getSessionPeer(java.lang.String) + */ + @Override + public String getSessionPeer(String sessionId) { + SessionEntry se = sessionIdToEntry.get(sessionId); + logger.debug("Looking up routing peer for session [{}]: {}", sessionId, se); + return (se != null && se instanceof RoutingAwareSessionEntry) ? ((RoutingAwareSessionEntry) se).peer : null; + } + + /* + * (non-Javadoc) + * @see org.jdiameter.common.api.data.IRoutingAwareSessionDatasource#removeSessionPeer(java.lang.String) + */ + @Override + public String removeSessionPeer(String sessionId) { + SessionEntry se = sessionIdToEntry.get(sessionId); + logger.debug("Looking up routing peer for removal for session [{}]: {}", sessionId, se); + if (se != null && se instanceof RoutingAwareSessionEntry) { + String oldPeer = ((RoutingAwareSessionEntry) se).peer; + ((RoutingAwareSessionEntry) se).peer = null; + return oldPeer; + } else { + return null; + } + } + + /* + * (non-Javadoc) + * @see org.jdiameter.api.SessionPersistenceStorage#dumpStickySessions(int) + */ + @Override + public List dumpStickySessions(int maxLimit) { + int counter = 0; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + List sessions = maxLimit > 0 ? new ArrayList(maxLimit) : new ArrayList(sessionIdToEntry.size()); + + logger.debug("Reading [{}] sessions out of [{}]", maxLimit > 0 ? String.valueOf(maxLimit) : "unlimited", sessionIdToEntry.size()); + + for (Map.Entry entry : sessionIdToEntry.entrySet()) { + if (entry.getValue() instanceof RoutingAwareSessionEntry) { + RoutingAwareSessionEntry tmpEntry = (RoutingAwareSessionEntry) entry.getValue(); + if (tmpEntry.peer != null) { + sessions.add(tmpEntry.preetyPrint(entry.getKey(), dateFormat)); + if (maxLimit > 0 && ++counter >= maxLimit) { + break; + } + } + } + } + + return sessions; + } + + /** + * Extends basic session entry, which is used to store records in session storage, with extra info about + * a specific peer that is bound to a particular session. Extra info is used for session persistent routing. + */ + protected static class RoutingAwareSessionEntry extends SessionEntry { + String peer; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("RoutingAwareSessionEntry [peer=").append(peer).append(", toString()=").append(super.toString()).append("]"); + return builder.toString(); + } + + /** + * Gets a readable and more user friendly format of an entry. + * + * @param key key used to store that entry in a session storage map + * @param dateFormat format used to print last session activity timestamp + * @return readable representation of this session entry + */ + public String preetyPrint(String key, DateFormat dateFormat) { + StringBuilder builder = new StringBuilder("{id=["); + builder.append(key) + .append("], peer=[") + .append(peer).append("], timestamp=[") + .append(dateFormat.format(new Date(session.getLastAccessedTime()))) + .append("]}").toString(); + return builder.toString(); + } + } +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/FailureAwareRouter.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/FailureAwareRouter.java new file mode 100644 index 000000000..2951467fe --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/FailureAwareRouter.java @@ -0,0 +1,22 @@ +package org.jdiameter.server.impl; + +import org.jdiameter.api.Configuration; +import org.jdiameter.api.MetaData; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.client.api.controller.IRealmTable; +import org.jdiameter.common.api.concurrent.IConcurrentFactory; +import org.jdiameter.server.api.IRouter; + +/** + * Just a simple counterpart of failure aware router defined for a client role. + */ +public class FailureAwareRouter extends org.jdiameter.client.impl.router.FailureAwareRouter implements IRouter { + + /** + * Parameterized constructor. Should be called by any subclasses. + */ + public FailureAwareRouter(IContainer container, IConcurrentFactory concurrentFactory, IRealmTable realmTable, Configuration config, MetaData aMetaData) { + super(container, concurrentFactory, realmTable, config, aMetaData); + } + +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/PeerImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/PeerImpl.java index 1b8be7612..f4673bd9a 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/PeerImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/PeerImpl.java @@ -42,14 +42,6 @@ package org.jdiameter.server.impl; -import static org.jdiameter.api.PeerState.DOWN; -import static org.jdiameter.api.PeerState.INITIAL; - -import java.io.IOException; -import java.net.InetAddress; -import java.util.Map; -import java.util.Set; - import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; @@ -86,6 +78,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.InetAddress; +import java.util.Map; +import java.util.Set; + +import static org.jdiameter.api.PeerState.DOWN; +import static org.jdiameter.api.PeerState.INITIAL; + /** * * @author erick.svenson@yahoo.com @@ -205,9 +205,10 @@ public void notifyOvrManager(IOverloadManager ovrManager) { @Override public String toString() { if (fsm != null) { - return "SPeer{" + "Uri=" + uri + "; State=" + fsm.getState(PeerState.class) + "; con=" + connection + "; incCon" + incConnections + " }"; + return "SPeer{" + "Uri=" + uri + "; State=" + fsm.getState(PeerState.class) + + "; Rating=" + rating + "; con="+ connection +"; incCon="+incConnections+" }"; } - return "SPeer{" + "Uri=" + uri + "; State=" + fsm + "; con=" + connection + "; incCon" + incConnections + " }"; + return "SPeer{" + "Uri=" + uri + "; State=" + fsm + "; Rating=" + rating + "; con="+ connection +"; incCon="+incConnections+" }"; } protected class LocalActionConext extends ActionContext { diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/ServerCCASessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/ServerCCASessionImpl.java index c3e2cf37e..b08e2641e 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/ServerCCASessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/ServerCCASessionImpl.java @@ -107,7 +107,7 @@ public class ServerCCASessionImpl extends AppCCASessionImpl implements ServerCCA public ServerCCASessionImpl(IServerCCASessionData data, ICCAMessageFactory fct, ISessionFactory sf, ServerCCASessionListener lst, IServerCCASessionContext ctx, StateChangeListener stLst) { - super(sf, data); + super(null, sf, data); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/ServerRoSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/ServerRoSessionImpl.java index 241b4a89e..ec2c7b9bb 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/ServerRoSessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/ServerRoSessionImpl.java @@ -108,7 +108,7 @@ public class ServerRoSessionImpl extends AppRoSessionImpl implements ServerRoSes public ServerRoSessionImpl(IServerRoSessionData sessionData, IRoMessageFactory fct, ISessionFactory sf, ServerRoSessionListener lst, IServerRoSessionContext ctx, StateChangeListener stLst) { - super(sf, sessionData); + super(null, sf, sessionData); if (sessionData == null) { throw new IllegalArgumentException("SessionData can not be null"); } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/fsm/PeerFSMImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/fsm/PeerFSMImpl.java index 0e5ae3ff3..0ff8aaac1 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/fsm/PeerFSMImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/fsm/PeerFSMImpl.java @@ -122,7 +122,7 @@ public boolean processEvent(StateEvent event) { } } catch (Throwable e) { - logger.debug("Can not send DWR", e); + logger.debug("Cannot send DWR", e); doDisconnect(); doEndConnection(); } @@ -140,7 +140,7 @@ public boolean processEvent(StateEvent event) { switchToNextState(STOPPING); } catch (Throwable e) { - logger.debug("Can not send DPR", e); + logger.debug("Cannot send DPR", e); doDisconnect(); switchToNextState(DOWN); } @@ -174,7 +174,7 @@ public boolean processEvent(StateEvent event) { context.sendDpaMessage(message(event), code, null); } catch (Throwable e) { - logger.debug("Can not send DPA", e); + logger.debug("Cannot send DPA", e); } IMessage message = (IMessage) event.getData(); try { @@ -202,7 +202,7 @@ public boolean processEvent(StateEvent event) { context.sendDwaMessage(message(event), ResultCode.SUCCESS, null); } catch (Throwable e) { - logger.debug("Can not send DWA, reconnecting", e); + logger.debug("Cannot send DWA, reconnecting", e); doDisconnect(); doEndConnection(); } @@ -216,7 +216,7 @@ public boolean processEvent(StateEvent event) { context.sendMessage(message(event)); } catch (Throwable e) { - logger.debug("Can not send message", e); + logger.debug("Cannot send message", e); doDisconnect(); doEndConnection(); } @@ -252,7 +252,7 @@ public boolean processEvent(StateEvent event) { switchToNextState(STOPPING); } catch (Throwable e) { - logger.debug("Can not send DPR", e); + logger.debug("Cannot send DPR", e); doDisconnect(); switchToNextState(DOWN); } @@ -269,7 +269,7 @@ public boolean processEvent(StateEvent event) { context.sendDpaMessage(message(event), code, null); } catch (Throwable e) { - logger.debug("Can not send DPA", e); + logger.debug("Cannot send DPA", e); } IMessage message = (IMessage) event.getData(); try { @@ -295,7 +295,7 @@ public boolean processEvent(StateEvent event) { switchToNextState(OKAY); } catch (Throwable e) { - logger.debug("Can not send DWA", e); + logger.debug("Cannot send DWA", e); doDisconnect(); switchToNextState(DOWN); } @@ -397,7 +397,7 @@ public boolean processEvent(StateEvent event) { switchToNextState(INITIAL); } catch (Throwable e) { - logger.debug("Can not send CER", e); + logger.debug("Cannot send CER", e); setTimer(REC_TIMEOUT); } break; @@ -406,7 +406,7 @@ public boolean processEvent(StateEvent event) { context.connect(); } catch (Exception e) { - logger.debug("Can not connect to remote peer", e); + logger.debug("Cannot connect to remote peer", e); setTimer(REC_TIMEOUT); } break; @@ -467,7 +467,7 @@ public boolean processEvent(StateEvent event) { switchToNextState(OKAY); // if other connection is win } catch (Exception e) { - logger.debug("Can not send CEA", e); + logger.debug("Cannot send CEA", e); doDisconnect(); doEndConnection(); } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/EmptyConfiguration.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/EmptyConfiguration.java index 13b3d89b1..46f8465e0 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/EmptyConfiguration.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/EmptyConfiguration.java @@ -42,6 +42,14 @@ package org.jdiameter.server.impl.helpers; +import org.jdiameter.api.ConfigurationListener; +import org.jdiameter.api.MutableConfiguration; +import org.jdiameter.client.impl.helpers.ExtensionPoint; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentConfiguration; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentProxy; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentRedirect; @@ -64,14 +72,6 @@ import static org.jdiameter.server.impl.helpers.ExtensionPoint.InternalNetworkGuard; import static org.jdiameter.server.impl.helpers.ExtensionPoint.InternalOverloadManager; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.jdiameter.api.ConfigurationListener; -import org.jdiameter.api.MutableConfiguration; -import org.jdiameter.client.impl.helpers.ExtensionPoint; - /** * This class allow create configuration class for stack * @@ -211,7 +211,22 @@ public void setByteArrayValue(int key, byte[] value) { } } - @Override + public void setIntArrayValue(int key, int[] value) { + List list = listeners.get(key); + if (list != null) { + boolean commit = true; + for (ConfigurationListener l : list) { + commit &= l.elementChanged(key, value); + } + if (commit) { + putValue(key, value); + } + } + else { + putValue(key, value); + } + } + public void setBooleanValue(int key, boolean value) { List list = listeners.get(key); if (list != null) { diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java index 0760eb62c..82b9406dd 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java @@ -42,6 +42,30 @@ package org.jdiameter.server.impl.helpers; +import org.jdiameter.api.Configuration; +import org.jdiameter.client.impl.helpers.AppConfiguration; +import org.jdiameter.client.impl.helpers.Ordinal; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentProxy; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentRedirect; import static org.jdiameter.client.impl.helpers.ExtensionPoint.InternalConcurrentEntityFactory; @@ -101,14 +125,16 @@ import static org.jdiameter.client.impl.helpers.Parameters.PropertyValue; import static org.jdiameter.client.impl.helpers.Parameters.QueueSize; import static org.jdiameter.client.impl.helpers.Parameters.RealmEntry; -import static org.jdiameter.client.impl.helpers.Parameters.RealmTable; import static org.jdiameter.client.impl.helpers.Parameters.RecTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionRequiredResCodes; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.SDEnableSessionCreation; import static org.jdiameter.client.impl.helpers.Parameters.SDName; import static org.jdiameter.client.impl.helpers.Parameters.SDProtocol; import static org.jdiameter.client.impl.helpers.Parameters.SDUseClientMode; import static org.jdiameter.client.impl.helpers.Parameters.Security; import static org.jdiameter.client.impl.helpers.Parameters.SecurityRef; +import static org.jdiameter.client.impl.helpers.Parameters.SessionInactivityTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.Statistics; import static org.jdiameter.client.impl.helpers.Parameters.StatisticsActiveList; import static org.jdiameter.client.impl.helpers.Parameters.StatisticsEnabled; @@ -123,6 +149,7 @@ import static org.jdiameter.client.impl.helpers.Parameters.ThreadPoolPriority; import static org.jdiameter.client.impl.helpers.Parameters.ThreadPoolSize; import static org.jdiameter.client.impl.helpers.Parameters.TrustData; +import static org.jdiameter.client.impl.helpers.Parameters.TxTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; import static org.jdiameter.client.impl.helpers.Parameters.VendorId; import static org.jdiameter.server.impl.helpers.ExtensionPoint.InternalNetWork; @@ -144,33 +171,9 @@ import static org.jdiameter.server.impl.helpers.Parameters.RealmHosts; import static org.jdiameter.server.impl.helpers.Parameters.RealmLocalAction; import static org.jdiameter.server.impl.helpers.Parameters.RealmName; +import static org.jdiameter.server.impl.helpers.Parameters.RealmTable; import static org.jdiameter.server.impl.helpers.Parameters.RequestTable; -import java.io.File; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.Source; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import org.jdiameter.api.Configuration; -import org.jdiameter.client.impl.helpers.AppConfiguration; -import org.jdiameter.client.impl.helpers.Ordinal; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - /** * This class provide loading and verification configuration for server from XML file * @@ -193,9 +196,9 @@ public XMLConfiguration(InputStream in) throws Exception { /** * Create instance of class and load file from defined input stream * - * @param in input stream + * @param in input stream * @param attributes attributes for DocumentBuilderFactory - * @param features features for DocumentBuilderFactory + * @param features features for DocumentBuilderFactory * @throws Exception */ public XMLConfiguration(InputStream in, Hashtable attributes, Hashtable features) throws Exception { @@ -215,9 +218,9 @@ public XMLConfiguration(String filename) throws Exception { /** * Create instance of class and load file from defined input stream * - * @param filename configuration file name + * @param filename configuration file name * @param attributes attributes for DocumentBuilderFactory - * @param features features for DocumentBuilderFactory + * @param features features for DocumentBuilderFactory * @throws Exception */ @@ -244,12 +247,10 @@ protected XMLConfiguration(Object in, Hashtable attributes, Hash if (in instanceof InputStream) { document = builder.parse((InputStream) in); - } - else if (in instanceof String) { + } else if (in instanceof String) { document = builder.parse(new File((String) in)); - } - else { - throw new Exception("Unknown type of input data"); + } else { + throw new Exception("Unknown type of input data"); } validate(document); @@ -272,17 +273,13 @@ protected void processing(Document document) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("LocalPeer")) { addLocalPeer(c.item(i)); - } - else if (nodeName.equals("Parameters")) { + } else if (nodeName.equals("Parameters")) { addParameters(c.item(i)); - } - else if (nodeName.equals("Security")) { + } else if (nodeName.equals("Security")) { addSecurity(c.item(i)); - } - else if (nodeName.equals("Network")) { + } else if (nodeName.equals("Network")) { addNetwork(c.item(i)); - } - else if (nodeName.equals("Extensions")) { + } else if (nodeName.equals("Extensions")) { addExtensions(c.item(i)); } } @@ -321,12 +318,10 @@ protected Configuration addApplicationID(Node node) { for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("VendorId")) { - e.add(VendorId, getLongValue(c.item(i))); - } - else if (nodeName.equals("AuthApplId")) { + e.add(VendorId, getLongValue(c.item(i))); + } else if (nodeName.equals("AuthApplId")) { e.add(AuthApplId, getLongValue(c.item(i))); - } - else if (nodeName.equals("AcctApplId")) { + } else if (nodeName.equals("AcctApplId")) { e.add(AcctApplId, getLongValue(c.item(i))); } } @@ -339,58 +334,61 @@ protected void addParameters(Node node) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("UseUriAsFqdn")) { add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); - } - else if (nodeName.equals("QueueSize")) { + } else if (nodeName.equals("QueueSize")) { add(QueueSize, getIntValue(c.item(i))); - } - else if (nodeName.equals("MessageTimeOut")) { + } else if (nodeName.equals("MessageTimeOut")) { add(MessageTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("StopTimeOut")) { + } else if (nodeName.equals("StopTimeOut")) { add(StopTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("CeaTimeOut")) { + } else if (nodeName.equals("CeaTimeOut")) { add(CeaTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("IacTimeOut")) { + } else if (nodeName.equals("IacTimeOut")) { add(IacTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("DwaTimeOut")) { + } else if (nodeName.equals("DwaTimeOut")) { add(DwaTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("DpaTimeOut")) { + } else if (nodeName.equals("DpaTimeOut")) { add(DpaTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("RecTimeOut")) { + } else if (nodeName.equals("RecTimeOut")) { add(RecTimeOut, getLongValue(c.item(i))); - } - else if (nodeName.equals("BindDelay")) { + } else if (nodeName.equals("BindDelay")) { add(BindDelay, getLongValue(c.item(i))); - } - else if (nodeName.equals("ThreadPool")) { + } else if (nodeName.equals("ThreadPool")) { addThreadPool(c.item(i)); - } - else if (nodeName.equals("PeerFSMThreadCount")) { + } else if (nodeName.equals("PeerFSMThreadCount")) { add(PeerFSMThreadCount, getIntValue(c.item(i))); - } - else if (nodeName.equals("Statistics")) { + } else if (nodeName.equals("Statistics")) { addStatisticLogger(Statistics, c.item(i)); - } - else if (nodeName.equals("Concurrent")) { + } else if (nodeName.equals("Concurrent")) { addConcurrent(Concurrent, c.item(i)); - } - else if (nodeName.equals("Dictionary")) { + } else if (nodeName.equals("Dictionary")) { addDictionary(Dictionary, c.item(i)); - } - else if (nodeName.equals("RequestTable")) { + } else if (nodeName.equals("RequestTable")) { addRequestTable(RequestTable, c.item(i)); - } - else { + } else if (nodeName.equals("SessionInactivityTimeOut")) { + add(SessionInactivityTimeOut, getIntValue(c.item(i))); + } else if (nodeName.equals("TxTimeOut")) { + add(TxTimeOut, getLongValue(c.item(i))); + } else if (nodeName.equals("RetransmissionTimeOut")) { + add(RetransmissionTimeOut, getLongValue(c.item(i))); + } else if (nodeName.equals("RetransmissionRequiredResCodes")) { + addRetransmissionRequiredResCodes(c.item(i)); + } else { appendOtherParameter(c.item(i)); } } } + protected void addRetransmissionRequiredResCodes(Node node) { + String[] codesArray = getValue(node).replaceAll(" ", "").split(","); + if (codesArray.length > 0) { + int[] parsedCodesArray = new int[codesArray.length]; + for (int i = 0; i < codesArray.length; i++) { + parsedCodesArray[i] = Integer.parseInt(codesArray[i]); + } + add(RetransmissionRequiredResCodes, parsedCodesArray); + } + } + protected void addThreadPool(Node item) { AppConfiguration threadPoolConfiguration = org.jdiameter.client.impl.helpers.EmptyConfiguration.getInstance(); NamedNodeMap attributes = item.getAttributes(); @@ -401,11 +399,9 @@ protected void addThreadPool(Node item) { int v = Integer.parseInt(n.getNodeValue()); if (n.getNodeName().equals("size")) { threadPoolConfiguration.add(ThreadPoolSize, v); - } - else if (n.getNodeName().equals("priority")) { + } else if (n.getNodeName().equals("priority")) { threadPoolConfiguration.add(ThreadPoolPriority, v); - } - else { + } else { //log.error("Unkonwn attribute on " + item.getNodeName() + ", attribute name: " + n.getNodeName()); } } @@ -457,11 +453,11 @@ protected void addStatisticLogger(org.jdiameter.client.impl.helpers.Parameters n active_records = (String) StatisticsActiveList.defValue(); } add(name, - getInstance(). - add(StatisticsLoggerPause, Long.parseLong(pause)). - add(StatisticsLoggerDelay, Long.parseLong(delay)). - add(StatisticsEnabled, Boolean.parseBoolean(enabled)). - add(StatisticsActiveList, active_records)); + getInstance(). + add(StatisticsLoggerPause, Long.parseLong(pause)). + add(StatisticsLoggerDelay, Long.parseLong(delay)). + add(StatisticsEnabled, Boolean.parseBoolean(enabled)). + add(StatisticsActiveList, active_records)); } protected void addDictionary(org.jdiameter.client.impl.helpers.Parameters name, Node node) { @@ -473,19 +469,19 @@ protected void addDictionary(org.jdiameter.client.impl.helpers.Parameters name, dicConfiguration.add(DictionaryClass, clazz); } - param = node.getAttributes().getNamedItem("enabled"); + param = node.getAttributes().getNamedItem("enabled"); if (param != null) { String enabled = param.getNodeValue(); dicConfiguration.add(DictionaryEnabled, Boolean.valueOf(enabled)); } - param = node.getAttributes().getNamedItem("sendLevel"); + param = node.getAttributes().getNamedItem("sendLevel"); if (param != null) { String sendLevel = param.getNodeValue(); dicConfiguration.add(DictionarySendLevel, sendLevel); } - param = node.getAttributes().getNamedItem("receiveLevel"); + param = node.getAttributes().getNamedItem("receiveLevel"); if (param != null) { String receiveLevel = param.getNodeValue(); dicConfiguration.add(DictionaryReceiveLevel, receiveLevel); @@ -506,7 +502,7 @@ protected void addRequestTable(org.jdiameter.client.impl.helpers.Parameters name param = node.getAttributes().getNamedItem("clear_size"); if (param != null) { String size = param.getNodeValue(); - tableConfiguration.add(Parameters.RequestTableClearSize, Integer.parseInt(size)); + tableConfiguration.add(Parameters.RequestTableClearSize, Integer.parseInt(size)); } add(name, tableConfiguration); @@ -526,9 +522,9 @@ protected void addSecurity(Node node) { protected Configuration addSecurityData(Node node) { AppConfiguration sd = getInstance().add(SDName, node.getAttributes().getNamedItem("name").getNodeValue()) - .add(SDProtocol, node.getAttributes().getNamedItem("protocol").getNodeValue()) - .add(SDEnableSessionCreation, Boolean.valueOf(node.getAttributes().getNamedItem("enable_session_creation").getNodeValue())) - .add(SDUseClientMode, Boolean.valueOf(node.getAttributes().getNamedItem("use_client_mode").getNodeValue())); + .add(SDProtocol, node.getAttributes().getNamedItem("protocol").getNodeValue()) + .add(SDEnableSessionCreation, Boolean.valueOf(node.getAttributes().getNamedItem("enable_session_creation").getNodeValue())) + .add(SDUseClientMode, Boolean.valueOf(node.getAttributes().getNamedItem("use_client_mode").getNodeValue())); NodeList c = node.getChildNodes(); @@ -540,27 +536,27 @@ protected Configuration addSecurityData(Node node) { } if (nodeName.equals("KeyData")) { sd.add(KeyData, getInstance().add(KDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) - .add(KDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) - .add(KDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) - .add(KDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); + .add(KDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) + .add(KDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) + .add(KDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } if (nodeName.equals("TrustData")) { sd.add(TrustData, getInstance().add(TDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) - .add(TDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) - .add(TDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) - .add(TDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); + .add(TDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) + .add(TDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) + .add(TDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } } return sd; } + protected void addNetwork(Node node) { NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Peers")) { addPeers(c.item(i)); - } - else if (nodeName.equals("Realms")) { + } else if (nodeName.equals("Realms")) { addRealms(c.item(i)); } } @@ -657,10 +653,10 @@ private void addOverloadMonitor(Node node) { private Configuration addOverloadMonitorItem(Node node) { return getInstance(). - add(OverloadEntryIndex, Integer.valueOf(getAttrValue(node, "index"))). - add(OverloadEntrylowThreshold, Double.valueOf(getAttrValue(node, "lowThreshold"))). - add(OverloadEntryhighThreshold, Double.valueOf(getAttrValue(node, "highThreshold"))). - add(ApplicationId, addApplicationID(node.getChildNodes())); + add(OverloadEntryIndex, Integer.valueOf(getAttrValue(node, "index"))). + add(OverloadEntrylowThreshold, Double.valueOf(getAttrValue(node, "lowThreshold"))). + add(OverloadEntryhighThreshold, Double.valueOf(getAttrValue(node, "highThreshold"))). + add(ApplicationId, addApplicationID(node.getChildNodes())); } protected void addIPAddress(Node node) { @@ -684,18 +680,18 @@ private void addIPAddresses(Node node) { protected Configuration addIPAddressItem(Node node) { return getInstance(). - add(OwnIPAddress, getValue(node)); + add(OwnIPAddress, getValue(node)); } protected Configuration addRealm(Node node) { AppConfiguration realmEntry = getInstance(); realmEntry. - add(ApplicationId, new Configuration[] {addApplicationID(node.getChildNodes())}). - add(RealmName, getAttrValue(node, "name")). - add(RealmHosts, getAttrValue(node, "peers")). - add(RealmLocalAction, getAttrValue(node, "local_action")). - add(RealmEntryIsDynamic, Boolean.valueOf(getAttrValue(node, "dynamic"))). - add(RealmEntryExpTime, Long.valueOf(getAttrValue(node, "exp_time"))); + add(ApplicationId, new Configuration[]{addApplicationID(node.getChildNodes())}). + add(RealmName, getAttrValue(node, "name")). + add(RealmHosts, getAttrValue(node, "peers")). + add(RealmLocalAction, getAttrValue(node, "local_action")). + add(RealmEntryIsDynamic, Boolean.valueOf(getAttrValue(node, "dynamic"))). + add(RealmEntryExpTime, Long.valueOf(getAttrValue(node, "exp_time"))); NodeList childNodes = node.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { @@ -761,71 +757,49 @@ protected void addExtensions(Node node) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("MetaData")) { addInternalExtension(InternalMetaData, getValue(c.item(i))); - } - else if (nodeName.equals("MessageParser")) { + } else if (nodeName.equals("MessageParser")) { addInternalExtension(InternalMessageParser, getValue(c.item(i))); - } - else if (nodeName.equals("ElementParser")) { + } else if (nodeName.equals("ElementParser")) { addInternalExtension(InternalElementParser, getValue(c.item(i))); - } - else if (nodeName.equals("RouterEngine")) { + } else if (nodeName.equals("RouterEngine")) { addInternalExtension(InternalRouterEngine, getValue(c.item(i))); - } - else if (nodeName.equals("PeerController")) { + } else if (nodeName.equals("PeerController")) { addInternalExtension(InternalPeerController, getValue(c.item(i))); - } - else if (nodeName.equals("RealmController")) { + } else if (nodeName.equals("RealmController")) { addInternalExtension(InternalRealmController, getValue(c.item(i))); - } - else if (nodeName.equals("SessionFactory")) { + } else if (nodeName.equals("SessionFactory")) { addInternalExtension(InternalSessionFactory, getValue(c.item(i))); - } - else if (nodeName.equals("TransportFactory")) { + } else if (nodeName.equals("TransportFactory")) { addInternalExtension(InternalTransportFactory, getValue(c.item(i))); - } - else if (nodeName.equals("Connection")) { + } else if (nodeName.equals("Connection")) { addInternalExtension(InternalConnectionClass, getValue(c.item(i))); - } - else if (nodeName.equals("NetworkGuard")) { + } else if (nodeName.equals("NetworkGuard")) { addInternalExtension(InternalNetworkGuard, getValue(c.item(i))); - } - else if (nodeName.equals("PeerFsmFactory")) { + } else if (nodeName.equals("PeerFsmFactory")) { addInternalExtension(InternalPeerFsmFactory, getValue(c.item(i))); - } - else if (nodeName.equals("StatisticFactory")) { + } else if (nodeName.equals("StatisticFactory")) { addInternalExtension(InternalStatisticFactory, getValue(c.item(i))); - } - else if (nodeName.equals("ConcurrentFactory")) { + } else if (nodeName.equals("ConcurrentFactory")) { addInternalExtension(InternalConcurrentFactory, getValue(c.item(i))); - } - else if (nodeName.equals("ConcurrentEntityFactory")) { + } else if (nodeName.equals("ConcurrentEntityFactory")) { addInternalExtension(InternalConcurrentEntityFactory, getValue(c.item(i))); - } - else if (nodeName.equals("StatisticProcessor")) { + } else if (nodeName.equals("StatisticProcessor")) { addInternalExtension(InternalStatisticProcessor, getValue(c.item(i))); - } - else if (nodeName.equals("NetWork")) { + } else if (nodeName.equals("NetWork")) { addInternalExtension(InternalNetWork, getValue(c.item(i))); - } - else if (nodeName.equals("SessionDatasource")) { + } else if (nodeName.equals("SessionDatasource")) { addInternalExtension(InternalSessionDatasource, getValue(c.item(i))); - } - else if (nodeName.equals("TimerFacility")) { + } else if (nodeName.equals("TimerFacility")) { addInternalExtension(InternalTimerFacility, getValue(c.item(i))); - } - else if (nodeName.equals("AgentRedirect")) { + } else if (nodeName.equals("AgentRedirect")) { addInternalExtension(InternalAgentRedirect, getValue(c.item(i))); - } - else if (nodeName.equals("AgentConfiguration")) { + } else if (nodeName.equals("AgentConfiguration")) { add(org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentConfiguration, getValue(c.item(i))); - } - else if (nodeName.equals("AgentProxy")) { + } else if (nodeName.equals("AgentProxy")) { addInternalExtension(InternalAgentProxy, getValue(c.item(i))); - } - else if (nodeName.equals("OverloadManager")) { + } else if (nodeName.equals("OverloadManager")) { addInternalExtension(InternalOverloadManager, getValue(c.item(i))); - } - else { + } else { appendOtherExtension(c.item(i)); } } diff --git a/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd b/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd index d283ced65..0939b5359 100644 --- a/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd +++ b/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd @@ -215,6 +215,38 @@ + + + Tx timer as described in chapter 13. of RFC 4006 defined in miliseconds. + + + + + + + + Retransmission stop timer which defines how long the stack should carry on with retransmissions in case of delivery failures. + + + + + + + + Comma delimited list of result codes which make an initial request to be retransmitted. + + + + + + + + Session inactivity timeout in seconds used for session persistence. + + + + + Peer FSM Thread Count. diff --git a/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd b/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd index b30936af1..ae0cb3640 100644 --- a/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd +++ b/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd @@ -280,6 +280,38 @@ + + + Tx timer as described in chapter 13. of RFC 4006 defined in miliseconds. + + + + + + + + Retransmission stop timer which defines how long the stack should carry on with retransmissions in case of delivery failures. + + + + + + + + Comma delimited list of result codes which make an initial request to be retransmitted. + + + + + + + + Session inactivity timeout in seconds used for session persistence. + + + + + Server Socket bind delay in milliseconds. diff --git a/core/mux/common/config/jdiameter-config.xml b/core/mux/common/config/jdiameter-config_baseline.xml similarity index 100% rename from core/mux/common/config/jdiameter-config.xml rename to core/mux/common/config/jdiameter-config_baseline.xml diff --git a/core/mux/common/config/jdiameter-config_ext_routing_failover.xml b/core/mux/common/config/jdiameter-config_ext_routing_failover.xml new file mode 100644 index 000000000..de658be55 --- /dev/null +++ b/core/mux/common/config/jdiameter-config_ext_routing_failover.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexer.java b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexer.java index d033edf2e..05afdf0c3 100644 --- a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexer.java +++ b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexer.java @@ -42,48 +42,6 @@ package org.mobicents.diameter.stack; -import static org.jdiameter.client.impl.helpers.Parameters.CeaTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.Concurrent; -import static org.jdiameter.client.impl.helpers.Parameters.ConcurrentEntityDescription; -import static org.jdiameter.client.impl.helpers.Parameters.ConcurrentEntityName; -import static org.jdiameter.client.impl.helpers.Parameters.ConcurrentEntityPoolSize; -import static org.jdiameter.client.impl.helpers.Parameters.DpaTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.DwaTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.IacTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.MessageTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.OwnDiameterURI; -import static org.jdiameter.client.impl.helpers.Parameters.OwnIPAddress; -import static org.jdiameter.client.impl.helpers.Parameters.OwnRealm; -import static org.jdiameter.client.impl.helpers.Parameters.OwnVendorID; -import static org.jdiameter.client.impl.helpers.Parameters.RealmEntry; -import static org.jdiameter.client.impl.helpers.Parameters.RealmTable; -import static org.jdiameter.client.impl.helpers.Parameters.RecTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.StatisticsLoggerDelay; -import static org.jdiameter.client.impl.helpers.Parameters.StatisticsLoggerPause; -import static org.jdiameter.client.impl.helpers.Parameters.StopTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; -import static org.jdiameter.server.impl.helpers.Parameters.AcceptUndefinedPeer; -import static org.jdiameter.server.impl.helpers.Parameters.DuplicateTimer; -import static org.jdiameter.server.impl.helpers.Parameters.OwnIPAddresses; -import static org.jdiameter.server.impl.helpers.Parameters.RealmHosts; -import static org.jdiameter.server.impl.helpers.Parameters.RealmName; - -import java.io.InputStream; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantLock; -import java.util.regex.Pattern; - -import javax.management.MBeanException; - import org.jboss.system.ServiceMBeanSupport; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationAlreadyUseException; @@ -103,6 +61,7 @@ import org.jdiameter.api.Request; import org.jdiameter.api.ResultCode; import org.jdiameter.api.Session; +import org.jdiameter.api.SessionPersistenceStorage; import org.jdiameter.api.Stack; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.client.api.controller.IRealmTable; @@ -120,6 +79,51 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.management.MBeanException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import java.util.regex.Pattern; + +import static org.jdiameter.client.impl.helpers.Parameters.CeaTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.Concurrent; +import static org.jdiameter.client.impl.helpers.Parameters.ConcurrentEntityDescription; +import static org.jdiameter.client.impl.helpers.Parameters.ConcurrentEntityName; +import static org.jdiameter.client.impl.helpers.Parameters.ConcurrentEntityPoolSize; +import static org.jdiameter.client.impl.helpers.Parameters.DpaTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.DwaTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.IacTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.MessageTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.OwnDiameterURI; +import static org.jdiameter.client.impl.helpers.Parameters.OwnIPAddress; +import static org.jdiameter.client.impl.helpers.Parameters.OwnRealm; +import static org.jdiameter.client.impl.helpers.Parameters.OwnVendorID; +import static org.jdiameter.client.impl.helpers.Parameters.RealmEntry; +import static org.jdiameter.client.impl.helpers.Parameters.RealmTable; +import static org.jdiameter.client.impl.helpers.Parameters.RecTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionRequiredResCodes; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.SessionInactivityTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.StatisticsLoggerDelay; +import static org.jdiameter.client.impl.helpers.Parameters.StatisticsLoggerPause; +import static org.jdiameter.client.impl.helpers.Parameters.StopTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.TxTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; +import static org.jdiameter.server.impl.helpers.Parameters.AcceptUndefinedPeer; +import static org.jdiameter.server.impl.helpers.Parameters.DuplicateTimer; +import static org.jdiameter.server.impl.helpers.Parameters.OwnIPAddresses; +import static org.jdiameter.server.impl.helpers.Parameters.RealmHosts; +import static org.jdiameter.server.impl.helpers.Parameters.RealmName; + /** * * @author Alexandre Mendonca @@ -584,6 +588,7 @@ public void unregisterListener(DiameterListener listener) { * n QueueSize */ + private static final String NEW_LINE = System.getProperty("line.separator"); private final String DEFAULT_STRING = "default_string"; private MutableConfiguration getMutableConfiguration() throws MBeanException { @@ -849,6 +854,31 @@ public void _Parameters_setRecTimeout(long stopTimeout) throws MBeanException { getMutableConfiguration().setLongValue(RecTimeOut.ordinal(), stopTimeout); } + public void _Parameters_setSessionInactivityTimeout(int timeout) throws MBeanException { + getMutableConfiguration().setIntValue(SessionInactivityTimeOut.ordinal(), timeout); + } + + public void _Parameters_setTxTimeout(long txTimeout) throws MBeanException { + getMutableConfiguration().setLongValue(TxTimeOut.ordinal(), txTimeout); + } + + public void _Parameters_setRetransmissionTimeout(long retransmissionTimeout) throws MBeanException { + getMutableConfiguration().setLongValue(RetransmissionTimeOut.ordinal(), retransmissionTimeout); + } + + public void _Parameters_setRetransmissionRequiredResCodes(String resCodes) throws MBeanException { + if(resCodes != null && resCodes.length() > 0) { + String[] codesArray = resCodes.replaceAll(" ", "").split(","); + if(codesArray.length > 0) { + int[] parsedCodesArray = new int[codesArray.length]; + for(int i=0; i < codesArray.length; i++) { + parsedCodesArray[i] = Integer.parseInt(codesArray[i]); + } + getMutableConfiguration().setIntArrayValue(RetransmissionRequiredResCodes.ordinal(), parsedCodesArray); + } + } + } + @Override public void _Parameters_setConcurrentEntity(String name, String desc, Integer size) throws MBeanException { for (Configuration c : getMutableConfiguration().getChildren(Concurrent.ordinal())) { @@ -989,5 +1019,23 @@ public boolean _Network_Peers_isPeerConnected(String name) throws MBeanException } } + public String _Network_Sessions_getPersistenceMap(int maxLimit) throws MBeanException { + try { + SessionPersistenceStorage sds = stack.getSessionPersistenceStorage(); + if(sds == null) { + return "Session persistence is not supported in current configuration!!"; + } + + StringBuilder sb = new StringBuilder(); + List sessions = sds.dumpStickySessions(maxLimit); + for(String session : sessions) { + sb.append(session).append(NEW_LINE); + } + return sb.length() > 0 ? sb.toString() : "No sessions found"; + } + catch (Exception e) { + throw new MBeanException(e, "Failed to get session storage"); + } + } } diff --git a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexerMBean.java b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexerMBean.java index 8599ac34f..f37f50446 100644 --- a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexerMBean.java +++ b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackMultiplexerMBean.java @@ -42,11 +42,6 @@ package org.mobicents.diameter.stack; -import java.net.InetAddress; -import java.util.Set; - -import javax.management.MBeanException; - import org.jboss.system.ServiceMBean; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Stack; @@ -54,6 +49,10 @@ import org.mobicents.diameter.api.DiameterProvider; import org.mobicents.diameter.stack.management.DiameterConfiguration; +import javax.management.MBeanException; +import java.net.InetAddress; +import java.util.Set; + /** * * @author Alexandre Mendonca @@ -207,6 +206,43 @@ public interface DiameterStackMultiplexerMBean extends ServiceMBean { */ void _Parameters_setRecTimeout(long recTimeout) throws MBeanException; + /** + * Sets the timeout value for session inactivity timer which defines how much time + * the persistence record should be kept if there is no request sent within a session. + * Irrelevant when session persistent routing is not enabled, defaults to 1800 seconds. + * + * @param timeout the amount of time, in seconds. + * @throws MBeanException if the operation is unable to perform correctly + */ + void _Parameters_setSessionInactivityTimeout(int timeout) throws MBeanException; + + /** + * Sets the waiting time in the client in the Pending state. (default: 10000, 10 seconds). + * + * @param txTimeout the amount of time, in ms. + * @throws MBeanException if the operation is unable to perform correctly + */ + void _Parameters_setTxTimeout(long txTimeout) throws MBeanException; + + /** + * Defines one of failover algorithm stop conditions. Namely, in case of consecutive peers + * failures the failover algorithm will try to retransmit a given message to other peers + * until retransmission timeout expires + * + * @param retransmissionTimeout the amount of time, in ms. + * @throws MBeanException if the operation is unable to perform correctly + */ + void _Parameters_setRetransmissionTimeout(long retransmissionTimeout) throws MBeanException; + + /** + * Defines a list of result codes which make an initial request to be retransmitted to + * another remote peer. + * + * @param resCodes comma delimited list of result codes + * @throws MBeanException if the operation is unable to perform correctly + */ + void _Parameters_setRetransmissionRequiredResCodes(String resCodes) throws MBeanException; + void _Parameters_setConcurrentEntity(String name, String desc, Integer size) throws MBeanException; void _Parameters_setStatisticLoggerDelay(long delay) throws MBeanException; @@ -337,4 +373,14 @@ void _Network_Realms_addRealm(String name, String peers, long appVendorId, long boolean _Network_Peers_isPeerConnected(String name) throws MBeanException; + // Sessions : routing persistence map ------------------------------------ + + /** + * Gets the current state of session persistence map used for routing and lists + * all sticky sessions that are currently in operation. + * + * @param maxLimit maximum number of records to be listed (0 corresponds to no limit) + * @throws MBeanException if the operation is unable to perform correctly + */ + String _Network_Sessions_getPersistenceMap(int maxLimit) throws MBeanException; } diff --git a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackProxy.java b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackProxy.java index 4269380ff..88e2cbb03 100644 --- a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackProxy.java +++ b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/DiameterStackProxy.java @@ -42,11 +42,6 @@ package org.mobicents.diameter.stack; -import java.io.IOException; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.logging.Logger; - import org.jdiameter.api.AvpDataException; import org.jdiameter.api.BaseSession; import org.jdiameter.api.Configuration; @@ -57,6 +52,7 @@ import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; +import org.jdiameter.api.SessionPersistenceStorage; import org.jdiameter.api.Stack; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.client.api.IAssembler; @@ -65,6 +61,11 @@ import org.jdiameter.client.api.StackState; import org.jdiameter.common.api.concurrent.IConcurrentFactory; +import java.io.IOException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + public class DiameterStackProxy implements Stack, IContainer { protected Stack realStack = null; @@ -174,6 +175,11 @@ public IAssembler getAssemblerFacility() { return ((IContainer) realStack).getAssemblerFacility(); } + @Override + public SessionPersistenceStorage getSessionPersistenceStorage() { + return ((IContainer)realStack).getSessionPersistenceStorage(); + } + /* (non-Javadoc) * @see org.jdiameter.api.Stack#getDictionary() */ @@ -181,5 +187,4 @@ public IAssembler getAssemblerFacility() { public Dictionary getDictionary() throws IllegalDiameterStateException { return realStack.getDictionary(); } - } diff --git a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/Parameters.java b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/Parameters.java index 3e60ed1e7..9ffd7470e 100644 --- a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/Parameters.java +++ b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/Parameters.java @@ -95,6 +95,14 @@ public interface Parameters extends Serializable { void setRecTimeout(long recTimeout); + int getSessionInactivityTimeout(); + + void setSessionInactivityTimeout(long sessionInactivityTimeout); + + long getTxTimeout(); + + void setTxTimeout(long txTimeout); + /* Gone since merge with build-350 public String getThreadPool_Priority(); diff --git a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/ParametersImpl.java b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/ParametersImpl.java index 17f29e8f7..408b72c4d 100644 --- a/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/ParametersImpl.java +++ b/core/mux/jar/src/main/java/org/mobicents/diameter/stack/management/ParametersImpl.java @@ -42,6 +42,15 @@ package org.mobicents.diameter.stack.management; +import org.jdiameter.api.Configuration; +import org.jdiameter.api.MutableConfiguration; +import org.mobicents.diameter.stack.management.ConcurrentEntity.ConcurrentEntityNames; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashMap; + import static org.jdiameter.client.impl.helpers.Parameters.CeaTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.Concurrent; import static org.jdiameter.client.impl.helpers.Parameters.ConcurrentEntityDescription; @@ -53,22 +62,18 @@ import static org.jdiameter.client.impl.helpers.Parameters.MessageTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.QueueSize; import static org.jdiameter.client.impl.helpers.Parameters.RecTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionRequiredResCodes; +import static org.jdiameter.client.impl.helpers.Parameters.RetransmissionTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.SessionInactivityTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.StatisticsLoggerDelay; import static org.jdiameter.client.impl.helpers.Parameters.StatisticsLoggerPause; import static org.jdiameter.client.impl.helpers.Parameters.StopTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.TxTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; import static org.jdiameter.server.impl.helpers.Parameters.AcceptUndefinedPeer; import static org.jdiameter.server.impl.helpers.Parameters.DuplicateProtection; import static org.jdiameter.server.impl.helpers.Parameters.DuplicateTimer; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.HashMap; - -import org.jdiameter.api.Configuration; -import org.jdiameter.api.MutableConfiguration; -import org.mobicents.diameter.stack.management.ConcurrentEntity.ConcurrentEntityNames; - public class ParametersImpl implements Parameters { private static final long serialVersionUID = 1L; @@ -93,6 +98,10 @@ public class ParametersImpl implements Parameters { private long dwaTimeout; private long dpaTimeout; private long recTimeout; + private long txTimeout; + private long retransmissionTimeOut; + private String retransmissionRequiredResCodes; + private int sessionInactivityTimeout; // Gone since merge with build-350 // private String threadPool_Priority; @@ -119,6 +128,10 @@ public ParametersImpl(MutableConfiguration config) { this.dwaTimeout = config.getLongValue(DwaTimeOut.ordinal(), 10000L); this.dpaTimeout = config.getLongValue(DpaTimeOut.ordinal(), 5000L); this.recTimeout = config.getLongValue(RecTimeOut.ordinal(), 10000L); + this.txTimeout = config.getLongValue(TxTimeOut.ordinal(), 10000); + this.retransmissionTimeOut = config.getLongValue(RetransmissionTimeOut.ordinal(), 45000L); + this.retransmissionRequiredResCodes = Arrays.toString(config.getIntArrayValue(RetransmissionRequiredResCodes.ordinal(), null)); + this.sessionInactivityTimeout = config.getIntValue(SessionInactivityTimeOut.ordinal(), 600); // Concurrent Entities for (Configuration concurrentEntity : config.getChildren(Concurrent.ordinal())) { @@ -253,6 +266,38 @@ public void setRecTimeout(long recTimeout) { DiameterConfiguration.getMutableConfiguration().setLongValue(RecTimeOut.ordinal(), recTimeout); } + public int getSessionInactivityTimeout() { + return sessionInactivityTimeout; + } + + public void setSessionInactivityTimeout(long sessionInactivityTimeout) { + DiameterConfiguration.getMutableConfiguration().setLongValue(SessionInactivityTimeOut.ordinal(), sessionInactivityTimeout); + } + + public long getTxTimeout() { + return txTimeout; + } + + public void setTxTimeout(long txTimeout) { + DiameterConfiguration.getMutableConfiguration().setLongValue(TxTimeOut.ordinal(), txTimeout); + } + + public long getRetransmissionTimeout() { + return retransmissionTimeOut; + } + + public void setRetransmissionTimeout(long retrTimeout) { + DiameterConfiguration.getMutableConfiguration().setLongValue(RetransmissionTimeOut.ordinal(), retrTimeout); + } + + public String getRetransmissionRequiredResCodes() { + return retransmissionRequiredResCodes; + } + + public void setTxTimeout(int[] resCodes) { + DiameterConfiguration.getMutableConfiguration().setIntArrayValue(RetransmissionRequiredResCodes.ordinal(), resCodes); + } + /* Gone since merge with build-350 public String getThreadPool_Priority() { return threadPool_Priority; diff --git a/core/mux/pom.xml b/core/mux/pom.xml index 242066793..442de5580 100644 --- a/core/mux/pom.xml +++ b/core/mux/pom.xml @@ -17,6 +17,8 @@ 1.5.9.0-build538-SNAPSHOT 1.1.0-SNAPSHOT + + jdiameter-config_baseline.xml pom @@ -93,6 +95,12 @@ sar-jboss-7 + + failover-config-enabled + + jdiameter-config_ext_routing_failover.xml + + diff --git a/core/mux/sar-jboss-4/pom.xml b/core/mux/sar-jboss-4/pom.xml index 7b6ab17bd..2027b3916 100644 --- a/core/mux/sar-jboss-4/pom.xml +++ b/core/mux/sar-jboss-4/pom.xml @@ -43,9 +43,19 @@ ${basedir}/target/classes/config - ../common/config - false - + ../common/config + false + + jdiameter-config_*.xml + + + + ../common/config + false + + ${jdiameter.mux.config.file} + + @@ -141,6 +151,7 @@ + diff --git a/core/mux/sar-jboss-5/pom.xml b/core/mux/sar-jboss-5/pom.xml index 98f159b29..ad475c141 100644 --- a/core/mux/sar-jboss-5/pom.xml +++ b/core/mux/sar-jboss-5/pom.xml @@ -45,7 +45,17 @@ ../common/config false + + jdiameter-config_*.xml + + + ../common/config + false + + ${jdiameter.mux.config.file} + + @@ -141,7 +151,8 @@ - + + diff --git a/core/mux/sar-jboss-7/pom.xml b/core/mux/sar-jboss-7/pom.xml index 3a1c2a541..b4c853908 100644 --- a/core/mux/sar-jboss-7/pom.xml +++ b/core/mux/sar-jboss-7/pom.xml @@ -150,8 +150,10 @@ + + From c92964ae4c0629c55fa7130ba8f27feeaafccbaf Mon Sep 17 00:00:00 2001 From: Bartosz Krok Date: Wed, 5 Apr 2017 11:00:24 +0200 Subject: [PATCH 2/2] Fix for issue#36 --- .../ro/ClientRoSessionDataReplicatedImpl.java | 113 ++--- .../api/NoMorePeersAvailableException.java | 7 +- .../api/ro/ClientRoSessionListener.java | 120 +++-- .../org/jdiameter/client/api/IMessage.java | 114 +++-- .../app/ro/ClientRoSessionDataLocalImpl.java | 93 ++-- .../impl/app/ro/ClientRoSessionImpl.java | 442 +++++++++++------- .../impl/app/ro/IClientRoSessionData.java | 69 ++- .../client/impl/controller/PeerImpl.java | 197 +++----- .../client/impl/parser/MessageImpl.java | 152 ++---- .../impl/router/FailureAwareRouter.java | 127 ++--- .../client/impl/router/RouterImpl.java | 182 ++++---- .../api/app/ro/IClientRoSessionContext.java | 65 +-- .../data/IRoutingAwareSessionDatasource.java | 13 + .../impl/app/AppRoutingAwareSessionImpl.java | 15 +- .../impl/app/ro/RoSessionFactoryImpl.java | 89 ++-- .../impl/data/RoutingAwareDataSource.java | 41 +- .../server/impl/MutablePeerTableImpl.java | 170 ++++--- 17 files changed, 982 insertions(+), 1027 deletions(-) diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java index b8e86fb86..a48872051 100644 --- a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java @@ -1,50 +1,27 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.mobicents.diameter.impl.ha.client.ro; -import java.io.Serializable; -import java.nio.ByteBuffer; - import org.jboss.cache.Fqn; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; @@ -61,10 +38,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Serializable; +import java.nio.ByteBuffer; + /** - * * @author Bartosz Baranowski * @author Alexandre Mendonca + * @author Grzegorz Figiel (ProIDS sp. z o.o.) */ public class ClientRoSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientRoSessionData { @@ -80,13 +60,14 @@ public class ClientRoSessionDataReplicatedImpl extends AppSessionDataReplicatedI private static final String GRA = "GRA"; private static final String GDDFH = "GDDFH"; private static final String GCCFH = "GCCFH"; + private static final String GCCSF = "GCCSF"; private IMessageParser messageParser; /** * @param nodeFqn * @param mobicentsCluster - * @param iface + * @param container */ public ClientRoSessionDataReplicatedImpl(Fqn nodeFqn, MobicentsCluster mobicentsCluster, IContainer container) { super(nodeFqn, mobicentsCluster); @@ -102,13 +83,12 @@ public ClientRoSessionDataReplicatedImpl(Fqn nodeFqn, MobicentsCluster mobice /** * @param sessionId * @param mobicentsCluster - * @param iface + * @param container */ public ClientRoSessionDataReplicatedImpl(String sessionId, MobicentsCluster mobicentsCluster, IContainer container) { this(Fqn.fromRelativeElements(ReplicatedSessionDatasource.SESSIONS_FQN, sessionId), mobicentsCluster, container); } - @Override public boolean isEventBased() { if (exists()) { return toPrimitive((Boolean) getNode().get(EVENT_BASED), true); @@ -118,7 +98,6 @@ public boolean isEventBased() { } } - @Override public void setEventBased(boolean isEventBased) { if (exists()) { getNode().put(EVENT_BASED, isEventBased); @@ -128,7 +107,6 @@ public void setEventBased(boolean isEventBased) { } } - @Override public boolean isRequestTypeSet() { if (exists()) { return toPrimitive((Boolean) getNode().get(REQUEST_TYPE), false); @@ -138,7 +116,6 @@ public boolean isRequestTypeSet() { } } - @Override public void setRequestTypeSet(boolean requestTypeSet) { if (exists()) { getNode().put(REQUEST_TYPE, requestTypeSet); @@ -148,7 +125,6 @@ public void setRequestTypeSet(boolean requestTypeSet) { } } - @Override public ClientRoSessionState getClientRoSessionState() { if (exists()) { return (ClientRoSessionState) getNode().get(STATE); @@ -158,7 +134,6 @@ public ClientRoSessionState getClientRoSessionState() { } } - @Override public void setClientRoSessionState(ClientRoSessionState state) { if (exists()) { getNode().put(STATE, state); @@ -168,7 +143,6 @@ public void setClientRoSessionState(ClientRoSessionState state) { } } - @Override public Serializable getTxTimerId() { if (exists()) { return (Serializable) getNode().get(TXTIMER_ID); @@ -178,7 +152,6 @@ public Serializable getTxTimerId() { } } - @Override public void setTxTimerId(Serializable txTimerId) { if (exists()) { getNode().put(TXTIMER_ID, txTimerId); @@ -206,7 +179,6 @@ public void setRetransmissionTimerId(Serializable txTimerId) { } } - @Override public Request getTxTimerRequest() { if (exists()) { byte[] data = (byte[]) getNode().get(TXTIMER_REQUEST); @@ -228,7 +200,6 @@ public Request getTxTimerRequest() { } } - @Override public void setTxTimerRequest(Request txTimerRequest) { if (exists()) { if (txTimerRequest != null) { @@ -249,7 +220,6 @@ public void setTxTimerRequest(Request txTimerRequest) { } } - @Override public Request getBuffer() { byte[] data = (byte[]) getNode().get(BUFFER); if (data != null) { @@ -266,7 +236,6 @@ public Request getBuffer() { } } - @Override public void setBuffer(Request buffer) { if (buffer != null) { try { @@ -282,7 +251,6 @@ public void setBuffer(Request buffer) { } } - @Override public int getGatheredRequestedAction() { if (exists()) { return toPrimitive((Integer) getNode().get(GRA)); @@ -292,7 +260,6 @@ public int getGatheredRequestedAction() { } } - @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { if (exists()) { getNode().put(GRA, gatheredRequestedAction); @@ -302,7 +269,6 @@ public void setGatheredRequestedAction(int gatheredRequestedAction) { } } - @Override public int getGatheredCCFH() { if (exists()) { return toPrimitive((Integer) getNode().get(GCCFH)); @@ -312,7 +278,6 @@ public int getGatheredCCFH() { } } - @Override public void setGatheredCCFH(int gatheredCCFH) { if (exists()) { getNode().put(GCCFH, gatheredCCFH); @@ -322,7 +287,6 @@ public void setGatheredCCFH(int gatheredCCFH) { } } - @Override public int getGatheredDDFH() { if (exists()) { return toPrimitive((Integer) getNode().get(GDDFH)); @@ -332,7 +296,6 @@ public int getGatheredDDFH() { } } - @Override public void setGatheredDDFH(int gatheredDDFH) { if (exists()) { getNode().put(GDDFH, gatheredDDFH); @@ -342,4 +305,24 @@ public void setGatheredDDFH(int gatheredDDFH) { } } + @Override + public int getGatheredCCSF() { + if (exists()) { + return toPrimitive((Integer) getNode().get(GCCSF)); + } + else { + throw new IllegalStateException(); + } + } + + @Override + public void setGatheredCCSF(int gatheredCCSF) { + if (exists()) { + getNode().put(GCCSF, gatheredCCSF); + } + else { + throw new IllegalStateException(); + } + } + } diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java index 40f999a79..bf6fe2f2b 100644 --- a/core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/NoMorePeersAvailableException.java @@ -24,6 +24,8 @@ /** * Signals that no peer is available for routing. + * + * @author ProIDS sp. z o.o. */ public class NoMorePeersAvailableException extends RouteException { @@ -35,6 +37,7 @@ public class NoMorePeersAvailableException extends RouteException { /** * Constructor with reason string and routing details + * * @param message reason string */ public NoMorePeersAvailableException(String message, boolean spre, String rrcd, int lspr) { @@ -46,8 +49,9 @@ public NoMorePeersAvailableException(String message, boolean spre, String rrcd, /** * Constructor with reason string and parent exception + * * @param message message reason string - * @param cause parent exception + * @param cause parent exception */ public NoMorePeersAvailableException(String message, Throwable cause) { super(message, cause); @@ -55,6 +59,7 @@ public NoMorePeersAvailableException(String message, Throwable cause) { /** * Constructor with reason string + * * @param message reason string */ public NoMorePeersAvailableException(String message) { diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java index 9eae0683c..ebd3decf6 100644 --- a/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java @@ -1,44 +1,24 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * JBoss, Home of Professional Open Source + * Copyright 2010, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.api.ro; @@ -69,11 +49,11 @@ public interface ClientRoSessionListener { * * @param session parent application session (FSM) * @param request request object - * @param answer answer object - * @throws InternalException The InternalException signals that internal error has occurred. + * @param answer answer object + * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). - * @throws RouteException The NoRouteException signals that no route exist for a given realm. - * @throws OverloadException The OverloadException signals that destination host is overloaded. + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doCreditControlAnswer(ClientRoSession session, RoCreditControlRequest request, RoCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; @@ -83,10 +63,10 @@ void doCreditControlAnswer(ClientRoSession session, RoCreditControlRequest reque * * @param session parent application session (FSM) * @param request request object - * @throws InternalException The InternalException signals that internal error has occurred. + * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). - * @throws RouteException The NoRouteException signals that no route exist for a given realm. - * @throws OverloadException The OverloadException signals that destination host is overloaded. + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doReAuthRequest(ClientRoSession session, ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; @@ -96,25 +76,39 @@ void doReAuthRequest(ClientRoSession session, ReAuthRequest request) * * @param session parent application session (FSM) * @param request request object - * @param answer answer object - * @throws InternalException The InternalException signals that internal error has occurred. + * @param answer answer object + * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). - * @throws RouteException The NoRouteException signals that no route exist for a given realm. - * @throws OverloadException The OverloadException signals that destination host is overloaded. + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ClientRoSessionListener that message delivery timeout expired and there was no response from - * any of remote peers in spite of numerous retransmissions and performing failover algorithm. + * one of remote peers. + * + * @param session parent application session (FSM) + * @param msg request object + * @throws InternalException The InternalException signals that internal error has occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void doRequestTxTimeout(ClientRoSession session, Message msg, Peer peer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + /** + * Notifies this ClientRoSessionListener that message delivery timeout expired and there was no response from + * any of remote peers in spite of numerous retransmissions and performing failover algorithm if enabled. * * @param session parent application session (FSM) - * @param msg request object - * @throws InternalException The InternalException signals that internal error has occurred. + * @param msg request object + * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). - * @throws RouteException The NoRouteException signals that no route exist for a given realm. - * @throws OverloadException The OverloadException signals that destination host is overloaded. + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doRequestTimeout(ClientRoSession session, Message msg, Peer peer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; @@ -122,14 +116,14 @@ void doRequestTimeout(ClientRoSession session, Message msg, Peer peer) /** * Notifies this ClientRoSessionListener that message cannot be delivered due to lack of remote peers being available at the moment. * - * @param cause root cause containing detailed description + * @param cause root cause containing detailed description * @param session parent application session (FSM) - * @param msg request object - * @param peer last remote peer that has been selected for routing - * @throws InternalException The InternalException signals that internal error has occurred. + * @param msg request object + * @param peer last remote peer that has been selected for routing + * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). - * @throws RouteException The NoRouteException signals that no route exist for a given realm. - * @throws OverloadException The OverloadException signals that destination host is overloaded. + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doPeerUnavailability(RouteException cause, ClientRoSession session, Message msg, Peer peer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java index 907d111b3..0a635c591 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java @@ -1,44 +1,24 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * JBoss, Home of Professional Open Source + * Copyright 2006, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.client.api; @@ -52,11 +32,12 @@ * This interface extends basic message interface * Data: $Date: 2009/07/27 18:05:03 $ * Revision: $Revision: 1.2 $ - * @version 1.5.0.1 * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski + * @author Grzegorz Figiel (ProIDS sp. z o.o.) + * @version 1.5.0.1 */ public interface IMessage extends IRequest, IAnswer { @@ -76,45 +57,61 @@ public interface IMessage extends IRequest, IAnswer { int STATE_BUFFERED = 2; /** - * Stack received answer to this message + * Stack received answer to this message */ int STATE_ANSWERED = 3; + /** + * Default CC-Session-Failover AVP value - NOT_SUPPORTED(0) according to RFC 4006. + */ + int SESSION_FAILOVER_NOT_SUPPORTED_VALUE = 0; + + /** + * CC-Session-Failover AVP value - SUPPORTED(1) according to RFC 4006. + */ + int SESSION_FAILOVER_SUPPORTED_VALUE = 1; + /** * Return state of message + * * @return state of message */ int getState(); /** * Set new state + * * @param newState new state value */ void setState(int newState); /** * Return header applicationId + * * @return header applicationId */ long getHeaderApplicationId(); /** * Set header message application id + * * @param applicationId header message application id */ void setHeaderApplicationId(long applicationId); /** * Return flags as inteher + * * @return flags as inteher */ int getFlags(); /** * Create timer for request timout procedure + * * @param scheduledFacility timer facility - * @param timeOut value of timeout - * @param timeUnit time unit + * @param timeOut value of timeout + * @param timeUnit time unit */ void createTimer(ScheduledExecutorService scheduledFacility, long timeOut, TimeUnit timeUnit); @@ -130,54 +127,63 @@ public interface IMessage extends IRequest, IAnswer { /** * Set hop by hop id - * @param hopByHopId hopByHopId value + * + * @param hopByHopId hopByHopId value */ void setHopByHopIdentifier(long hopByHopId); /** * Set end by end id - * @param endByEndId endByEndId value + * + * @param endByEndId endByEndId value */ void setEndToEndIdentifier(long endByEndId); /** * Return attached peer + * * @return attached peer */ IPeer getPeer(); /** * Attach message to peer + * * @param peer attached peer */ void setPeer(IPeer peer); /** * Return application id + * * @return application id */ ApplicationId getSingleApplicationId(); /** * Return application id + * * @return application id */ ApplicationId getSingleApplicationId(long id); /** * Check timeout + * * @return true if request has timeout */ boolean isTimeOut(); /** * Tells if there are any timers set to monitor potential retransmissions + * * @return true if potential retransmissions will be handled */ boolean isRetransmissionSupervised(); /** * Marks that message to be under supervision timers guarding retransmissions + * * @param arg true if supervision is active */ void setRetransmissionSupervised(boolean arg); @@ -185,13 +191,20 @@ public interface IMessage extends IRequest, IAnswer { /** * Tells if the number of allowed retransmissions for this message is * already exceeded or not. + * * @return false if no more retransmissions are allowed */ boolean isRetransmissionAllowed(); + /** + * @return value of CC-Session-Failover AVP. + */ + int getCcSessionFailover(); + /** * Sets the number of allowed retransmissions for this message that can be performed * in case of failure detection. + * * @param arg number of allowed retransmissions */ void setNumberOfRetransAllowed(int arg); @@ -203,25 +216,29 @@ public interface IMessage extends IRequest, IAnswer { /** * Set event listener + * * @param listener event listener */ void setListener(IEventListener listener); /** * Return event listener + * * @return event listener */ IEventListener getEventListener(); /** * Return duplication key of message + * * @return duplication key of message */ String getDuplicationKey(); /** * Generate duplication key - * @param host origination host + * + * @param host origination host * @param endToEndId end to end id * @return duplication key */ @@ -229,6 +246,7 @@ public interface IMessage extends IRequest, IAnswer { /** * Create clone object + * * @return clone */ Object clone(); diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java index 926ae5890..90008255c 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java @@ -1,44 +1,24 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.client.impl.app.ro; @@ -49,9 +29,9 @@ import java.io.Serializable; /** - * * @author Bartosz Baranowski * @author Alexandre Mendonca + * @author Grzegorz Figiel (ProIDS sp. z o.o.) */ public class ClientRoSessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientRoSessionData { @@ -70,6 +50,7 @@ public class ClientRoSessionDataLocalImpl extends AppSessionDataLocalImpl implem protected int gatheredCCFH = NON_INITIALIZED; protected int gatheredDDFH = NON_INITIALIZED; + protected int gatheredCCSF = NON_INITIALIZED; /** * @@ -77,52 +58,42 @@ public class ClientRoSessionDataLocalImpl extends AppSessionDataLocalImpl implem public ClientRoSessionDataLocalImpl() { } - @Override public boolean isEventBased() { return isEventBased; } - @Override public void setEventBased(boolean isEventBased) { this.isEventBased = isEventBased; } - @Override public boolean isRequestTypeSet() { return requestTypeSet; } - @Override public void setRequestTypeSet(boolean requestTypeSet) { this.requestTypeSet = requestTypeSet; } - @Override public ClientRoSessionState getClientRoSessionState() { return state; } - @Override public void setClientRoSessionState(ClientRoSessionState state) { this.state = state; } - @Override public Serializable getTxTimerId() { return txTimerId; } - @Override public void setTxTimerId(Serializable txTimerId) { this.txTimerId = txTimerId; } - @Override public Request getTxTimerRequest() { return txTimerRequest; } - @Override public void setTxTimerRequest(Request txTimerRequest) { this.txTimerRequest = txTimerRequest; } @@ -135,44 +106,46 @@ public void setRetransmissionTimerId(Serializable retransmissionTimerId) { this.retransmissionTimerId = retransmissionTimerId; } - @Override public Request getBuffer() { return buffer; } - @Override public void setBuffer(Request buffer) { this.buffer = buffer; } - @Override public int getGatheredRequestedAction() { return gatheredRequestedAction; } - @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { this.gatheredRequestedAction = gatheredRequestedAction; } - @Override public int getGatheredCCFH() { return gatheredCCFH; } - @Override public void setGatheredCCFH(int gatheredCCFH) { this.gatheredCCFH = gatheredCCFH; } - @Override public int getGatheredDDFH() { return gatheredDDFH; } - @Override public void setGatheredDDFH(int gatheredDDFH) { this.gatheredDDFH = gatheredDDFH; } + @Override + public int getGatheredCCSF() { + return this.gatheredCCSF; + } + + @Override + public void setGatheredCCSF(int gatheredCCSF) { + this.gatheredCCSF = gatheredCCSF; + } + } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java index 254989ace..44dad7f07 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java @@ -1,43 +1,23 @@ /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. + * JBoss, Home of Professional Open Source + * Copyright 2010, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jdiameter.client.impl.app.ro; @@ -78,6 +58,7 @@ import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl; import org.jdiameter.common.impl.app.ro.AppRoSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,6 +81,7 @@ * * @author Alexandre Mendonca * @author Bartosz Baranowski + * @author Grzegorz Figiel (ProIDS sp. z o.o.) */ public class ClientRoSessionImpl extends AppRoSessionImpl implements ClientRoSession, NetworkReqListener, EventListener { @@ -166,8 +148,8 @@ public class ClientRoSessionImpl extends AppRoSessionImpl implements ClientRoSes // Session Based Queue protected ArrayList eventQueue = new ArrayList(); - public ClientRoSessionImpl(IClientRoSessionData sessionData, IRoMessageFactory fct, ISessionDatasource sds, ISessionFactory sf, - ClientRoSessionListener lst, IClientRoSessionContext ctx, StateChangeListener stLst) { + public ClientRoSessionImpl(IClientRoSessionData sessionData, IRoMessageFactory fct, ISessionDatasource sds, ISessionFactory sf, ClientRoSessionListener + lst, IClientRoSessionContext ctx, StateChangeListener stLst) { super(sds, sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); @@ -208,23 +190,26 @@ protected int getLocalDDFH() { return sessionData.getGatheredDDFH() >= 0 ? sessionData.getGatheredDDFH() : context.getDefaultDDFHValue(); } - @Override - public void sendCreditControlRequest(RoCreditControlRequest request) - throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + protected boolean isSessionFailoverSupported() { + return sessionData.getGatheredCCSF() > 0; + } + + + public void sendCreditControlRequest(RoCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, + OverloadException { try { extractFHAVPs(request, null); this.handleEvent(new Event(true, request, null)); - } catch (AvpDataException e) { + } + catch (AvpDataException e) { throw new InternalException(e); } } - @Override public void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { this.handleEvent(new Event(Event.Type.SEND_RAA, null, answer)); } - @Override public boolean isStateless() { return false; } @@ -233,13 +218,11 @@ public boolean isEventBased() { return sessionData.isEventBased(); } - @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ClientRoSessionState.class ? (E) sessionData.getClientRoSessionState() : null; } - @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return this.isEventBased() ? handleEventForEventBased(event) : handleEventForSessionBased(event); } @@ -263,7 +246,8 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce setState(ClientRoSessionState.PENDING_EVENT); try { dispatchEvent(localEvent.getRequest()); - } catch (Exception e) { + } + catch (Exception e) { // This handles failure to send in PendingI state in FSM table logger.debug("Failure handling send event request", e); handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); @@ -293,12 +277,14 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce } deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); - } catch (AvpDataException e) { + } + catch (AvpDataException e) { logger.debug("Failure handling received answer event", e); setState(ClientRoSessionState.IDLE, false); } break; case Tx_TIMER_FIRED: + deliverRequestTxTimeout(localEvent.getRequest().getMessage()); handleTxExpires(localEvent.getRequest().getMessage()); break; default: @@ -331,9 +317,11 @@ protected boolean handleEventForEventBased(StateEvent event) throws InternalExce dispatch(); return true; - } catch (Exception e) { + } + catch (Exception e) { throw new InternalException(e); - } finally { + } + finally { sendAndStateLock.unlock(); } } @@ -355,11 +343,16 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx // New State: PENDING_I startTx(localEvent.getRequest().getMessage()); setState(ClientRoSessionState.PENDING_INITIAL); + // RFC 4006: For new credit-control sessions, failover to an alternative + // credit-control server SHOULD be performed if possible. + sessionData.setGatheredCCSF(IMessage.SESSION_FAILOVER_SUPPORTED_VALUE); try { dispatchEvent(localEvent.getRequest()); - } catch (NoMorePeersAvailableException nmpae) { + } + catch (NoMorePeersAvailableException nmpae) { handlePeerUnavailability(localEvent.getRequest().getMessage(), nmpae); - } catch (Exception e) { + } + catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } @@ -374,6 +367,7 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_INITIAL_ANSWER: + sessionData.setGatheredCCSF(((IMessage) localEvent.getAnswer().getMessage()).getCcSessionFailover()); long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_I @@ -388,18 +382,21 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx initSessionPersistenceContext(localEvent.getRequest(), localEvent.getAnswer()); startSessionInactivityTimer(); } - } else if (retrRequiredErrorCodes.contains(resultCode)) { + } + else if (retrRequiredErrorCodes.contains(resultCode)) { handleRetransmissionDueToError(eventType, localEvent.getRequest().getMessage()); break; - } else if (isProvisional(resultCode) || isFailure(resultCode)) { + } + else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType); } deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: + deliverRequestTxTimeout(localEvent.getRequest().getMessage()); if (isRetransmissionRequired()) { - handleRetransmissionDueToTimeout(eventType, localEvent.getRequest().getMessage()); + handleRetransmissionDueToTimeout(eventType, localEvent.getRequest()); } else { handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); @@ -456,9 +453,11 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx setState(ClientRoSessionState.PENDING_UPDATE); try { dispatchEvent(localEvent.getRequest()); - } catch (NoMorePeersAvailableException nmpae) { + } + catch (NoMorePeersAvailableException nmpae) { handlePeerUnavailability(localEvent.getRequest().getMessage(), nmpae); - } catch (Exception e) { + } + catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } @@ -487,9 +486,11 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx setState(ClientRoSessionState.PENDING_TERMINATION); try { dispatchEvent(localEvent.getRequest()); - } catch (NoMorePeersAvailableException nmpae) { + } + catch (NoMorePeersAvailableException nmpae) { handlePeerUnavailability(localEvent.getRequest().getMessage(), nmpae); - } catch (Exception e) { + } + catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -499,7 +500,8 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx case SEND_RAA: try { dispatchEvent(localEvent.getAnswer()); - } catch (Exception e) { + } + catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -514,6 +516,7 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_UPDATE_ANSWER: + sessionData.setGatheredCCSF(((IMessage) localEvent.getAnswer().getMessage()).getCcSessionFailover()); long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_U @@ -522,18 +525,21 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx // New State: OPEN stopTx(); setState(ClientRoSessionState.OPEN); - } else if (retrRequiredErrorCodes.contains(resultCode)) { + } + else if (retrRequiredErrorCodes.contains(resultCode)) { handleRetransmissionDueToError(eventType, localEvent.getRequest().getMessage()); break; - } else if (isProvisional(resultCode) || isFailure(resultCode)) { + } + else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType); } deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: + deliverRequestTxTimeout(localEvent.getRequest().getMessage()); if (isRetransmissionRequired()) { - handleRetransmissionDueToTimeout(eventType, localEvent.getRequest().getMessage()); + handleRetransmissionDueToTimeout(eventType, localEvent.getRequest()); } else { handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); @@ -565,7 +571,8 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx // New State: PENDING_U try { dispatchEvent(localEvent.getAnswer()); - } catch (Exception e) { + } + catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; @@ -583,7 +590,8 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx // New State: PENDING_T dispatchEvent(localEvent.getRequest()); // No transition - } catch (Exception e) { + } + catch (Exception e) { // This handles failure to send in PendingI state in FSM table // handleSendFailure(e, eventType); } @@ -601,6 +609,7 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx //FIXME: Alex broke this, setting back "true" ? //setState(ClientRoSessionState.IDLE, false); + sessionData.setGatheredCCSF(((IMessage) localEvent.getAnswer().getMessage()).getCcSessionFailover()); long resultCode = ((AppAnswerEvent) localEvent.getAnswer()).getResultCodeAvp().getUnsigned32(); if (retrRequiredErrorCodes.contains(resultCode)) { handleRetransmissionDueToError(eventType, localEvent.getRequest().getMessage()); @@ -611,8 +620,9 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx setState(ClientRoSessionState.IDLE, true); break; case Tx_TIMER_FIRED: + deliverRequestTxTimeout(localEvent.getRequest().getMessage()); if (isRetransmissionRequired()) { - handleRetransmissionDueToTimeout(eventType, localEvent.getRequest().getMessage()); + handleRetransmissionDueToTimeout(eventType, localEvent.getRequest()); } else { handleRetransmissionFailure((RoCreditControlRequest) localEvent.getRequest()); @@ -634,14 +644,15 @@ protected boolean handleEventForSessionBased(StateEvent event) throws InternalEx dispatch(); return true; - } catch (Exception e) { + } + catch (Exception e) { throw new InternalException(e); - } finally { + } + finally { sendAndStateLock.unlock(); } } - @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; @@ -650,7 +661,6 @@ public Answer processRequest(Request request) { return null; } - @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery ad = new AnswerDelivery(); ad.session = this; @@ -660,16 +670,17 @@ public void receivedSuccessMessage(Request request, Answer answer) { } - @Override public void timeoutExpired(Request request) { if (request.getCommandCode() == RoCreditControlAnswer.code) { try { sendAndStateLock.lock(); stopTx(); handleSendFailure(null, null, request); - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Failure processing timeout message for request", e); - } finally { + } + finally { sendAndStateLock.unlock(); } } @@ -677,13 +688,12 @@ public void timeoutExpired(Request request) { protected void startTx(Message message) { stopTx(false); - if(logger.isDebugEnabled()) { - logger.debug("Scheduling Tx timer in [{}] ms", this.txTimerVal); - } + logger.debug("Scheduling Tx timer in [{}] ms", this.txTimerVal); try { sessionData.setTxTimerRequest((Request) message); sessionData.setTxTimerId(this.timerFacility.schedule(this.sessionData.getSessionId(), TX_TIMER_NAME, this.txTimerVal)); - } catch (Exception e) { + } + catch (Exception e) { throw new IllegalArgumentException("Failed to store request.", e); } } @@ -694,9 +704,7 @@ protected void stopTx(boolean stopDependant) { if (stopDependant) { stopFailoverStopTimer(); } - if(logger.isDebugEnabled()) { - logger.debug("Stopping Tx timer [{}]", txTimerId); - } + logger.debug("Stopping Tx timer [{}]", txTimerId); timerFacility.cancel(txTimerId); sessionData.setTxTimerId(null); sessionData.setTxTimerRequest(null); @@ -734,15 +742,19 @@ protected void stopFailoverStopTimer() { public void onTimer(String timerName) { if (timerName.equals(TX_TIMER_NAME)) { new TxTimerTask(this, sessionData.getTxTimerRequest()).run(); - } else if (timerName.equals(RETRANSMISSION_TIMER_NAME)) { + } + else if (timerName.equals(RETRANSMISSION_TIMER_NAME)) { new RetransmissionTimerTask(this, sessionData.getTxTimerRequest()).run(); - } else { + } + else { try { sendAndStateLock.lock(); super.onTimer(timerName); - } catch (Exception ex) { + } + catch (Exception ex) { logger.error("Cannot properly handle timer expiry", ex); - } finally { + } + finally { sendAndStateLock.unlock(); } } @@ -759,7 +771,7 @@ protected void setState(ClientRoSessionState newState, boolean release) { IAppSessionState oldState = state; sessionData.setClientRoSessionState(newState); for (StateChangeListener i : stateListeners) { - i.stateChanged(this, (Enum) oldState, (Enum) newState); + i.stateChanged(this, (Enum) oldState, newState); } if (newState == ClientRoSessionState.IDLE) { @@ -776,7 +788,8 @@ protected void setState(ClientRoSessionState newState, boolean release) { } } } - } catch (Exception e) { + } + catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure switching to state " + sessionData.getClientRoSessionState() + " (release=" + release + ")", e); } @@ -790,19 +803,24 @@ public void release() { this.sendAndStateLock.lock(); this.stopTx(); super.release(); - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Failed to release session", e); - } finally { + } + finally { this.sendAndStateLock.unlock(); } - } else { + } + else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void handleSendFailure(Exception e, Event.Type eventType, Message request) throws Exception { logger.warn("Failed to send message", e); - logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""}); + if (logger.isDebugEnabled()) { + logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""}); + } try { ClientRoSessionState state = sessionData.getClientRoSessionState(); // Event Based ---------------------------------------------------------- @@ -817,7 +835,8 @@ protected void handleSendFailure(Exception e, Event.Type eventType, Message requ // New State: IDLE setState(ClientRoSessionState.IDLE); context.indicateServiceError(this); - } else if (gatheredRequestedAction == DIRECT_DEBITING) { + } + else if (gatheredRequestedAction == DIRECT_DEBITING) { switch (getLocalDDFH()) { case DDFH_TERMINATE_OR_BUFFER: // Current State: PENDING_E @@ -831,7 +850,8 @@ protected void handleSendFailure(Exception e, Event.Type eventType, Message requ break; case DDFH_CONTINUE: // Current State: PENDING_E - // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE + // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to + // CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnDeliverFailure(this, request); @@ -839,7 +859,8 @@ protected void handleSendFailure(Exception e, Event.Type eventType, Message requ default: logger.warn("Invalid Direct-Debiting-Failure-Handling AVP value {}", getLocalDDFH()); } - } else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } + else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag @@ -847,7 +868,8 @@ protected void handleSendFailure(Exception e, Event.Type eventType, Message requ setState(ClientRoSessionState.IDLE, false); request.setReTransmitted(true); sessionData.setBuffer((Request) request); - } else { + } + else { logger.warn("Invalid Requested-Action AVP value {}", gatheredRequestedAction); } break; @@ -896,7 +918,8 @@ protected void handleSendFailure(Exception e, Event.Type eventType, Message requ break; } } - } finally { + } + finally { dispatch(); } } @@ -920,14 +943,17 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl context.denyAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { + } + else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { // Current State: PENDING_E - // Event: Failed answer or answer received w/ result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx expired + // Event: Failed answer or answer received with result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx + // expired // Action: - // New State: IDLE setState(ClientRoSessionState.IDLE); } - } else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { + } + else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { // Current State: PENDING_E // Event: CC event answer received with result code CREDIT_CONTROL_NOT_APPLICABLE; requested action DIRECT_DEBITING // Action: Grant service to end user @@ -935,7 +961,8 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } else if (temporaryErrorCodes.contains(resultCode)) { + } + else if (temporaryErrorCodes.contains(resultCode)) { if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY @@ -944,36 +971,43 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } else if (gatheredRequestedAction == DIRECT_DEBITING) { + } + else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E - // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE + // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to + // CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { + } + else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E - // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running + // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx + // running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } - } else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } + else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Temporary error, and requested action REFUND_ACCOUNT // Action: Store request // New State: IDLE sessionData.setBuffer((Request) request); setState(ClientRoSessionState.IDLE, false); - } else { - logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", - new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } - } else { // Failure + else { + logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, + resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); + } + } + else { // Failure if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY @@ -982,25 +1016,30 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } else if (gatheredRequestedAction == DIRECT_DEBITING) { + } + else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E - // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE + // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to + // CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { + } + else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E - // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running + // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx + // running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } - } else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } + else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failed CC event answer received; requested action REFUND_ACCOUNT // Action: Indicate service error and delete request @@ -1009,9 +1048,10 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); - } else { - logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", - new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); + } + else { + logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, + resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } break; @@ -1039,14 +1079,16 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { + } + else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { // Current State: PENDING_I // Event: CC initial answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } else { + } + else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: @@ -1081,14 +1123,16 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } else if (resultCode == END_USER_SERVICE_DENIED) { + } + else if (resultCode == END_USER_SERVICE_DENIED) { // Current State: PENDING_U // Event: CC update answer received with result code END_USER_SERVICE_DENIED // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); - } else { + } + else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: @@ -1119,7 +1163,8 @@ protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControl logger.warn("Wrong event type ({}) on state {}", eventType, state); } } - } catch (Exception e) { + } + catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure handling failure message for Event " + event + " (" + eventType + ") and Request " + request, e); } @@ -1139,7 +1184,8 @@ protected void handleTxExpires(Message message) { // New State: IDLE context.indicateServiceError(this); setState(ClientRoSessionState.IDLE); - } else if (gatheredRequestedAction == DIRECT_DEBITING) { + } + else if (gatheredRequestedAction == DIRECT_DEBITING) { if (sessionData.getGatheredDDFH() == DDFH_TERMINATE_OR_BUFFER) { // Current State: PENDING_E // Event: Temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER; Tx expired @@ -1147,7 +1193,8 @@ protected void handleTxExpires(Message message) { // New State: IDLE sessionData.setBuffer((Request) message); setState(ClientRoSessionState.IDLE, false); - } else { + } + else { // Current State: PENDING_E // Event: Tx expired; requested action DIRECT_DEBITING // Action: Grant service to end user @@ -1155,7 +1202,8 @@ protected void handleTxExpires(Message message) { context.grantAccessOnTxExpire(this); setState(ClientRoSessionState.PENDING_EVENT); } - } else if (gatheredRequestedAction == REFUND_ACCOUNT) { + } + else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag @@ -1233,8 +1281,9 @@ protected void handleTxExpires(Message message) { protected void handleRetransmissionFailure(RoCreditControlRequest req) { try { deliverRequestTimeout(req.getMessage()); - resetMessageStatus((IMessage) req.getMessage()); - } catch (InternalException e) { + resetMessageStatus(req.getMessage()); + } + catch (InternalException e) { logger.error("Cannot remove the expired message from either peer or rouoter tables for session [{}]", this.getSessionId()); } @@ -1242,6 +1291,10 @@ protected void handleRetransmissionFailure(RoCreditControlRequest req) { } protected void handlePeerUnavailability(Message msg, NoMorePeersAvailableException nmpae) { + logger.warn("No more peers available for sending diameter message: ", nmpae.getMessage()); + if (logger.isDebugEnabled()) { + logger.debug("nmpa exception: {}", nmpae); + } deliverPeerUnavailabilityError(msg, nmpae); resetMessageStatus(msg); setState(ClientRoSessionState.IDLE, true); @@ -1263,13 +1316,16 @@ protected void handleRetransmission(Type eventType, IMessage msg, boolean tFlagS try { dispatchEvent(msg); - } catch (NoMorePeersAvailableException nmpae) { + } + catch (NoMorePeersAvailableException nmpae) { handlePeerUnavailability(msg, nmpae); - } catch (Exception e1) { + } + catch (Exception e1) { logger.error("Cannot retransmit an old request", e1); try { handleSendFailure(e1, eventType, msg); - } catch (Exception e2) { + } + catch (Exception e2) { logger.error("Failure handling error", e2); } } @@ -1277,20 +1333,41 @@ protected void handleRetransmission(Type eventType, IMessage msg, boolean tFlagS protected void handleRetransmissionDueToError(Type eventType, Message msg) { IMessage imsg = (IMessage) msg; + logger.warn("Message will be retransmitted due to error response [{}] ", msg); - if (!imsg.isRetransmissionAllowed()) { - NoMorePeersAvailableException cause = new NoMorePeersAvailableException("No more peers available for retransmission"); - cause.setSessionPersistentRoutingEnabled(router.isSessionAware()); - handlePeerUnavailability(msg, cause); - return; + try { + if (imsg.isRetransmissionAllowed()) { + if (isSessionFailoverSupported()) { + handleRetransmission(eventType, imsg, false); + imsg.decrementNumberOfRetransAllowed(); + } + else { + handleSendFailure(new Exception("Failover unsupported for session ID: " + sessionData.getSessionId()), eventType, msg); + } + } + else { + NoMorePeersAvailableException cause = new NoMorePeersAvailableException("No more peers available for retransmission"); + cause.setSessionPersistentRoutingEnabled(router.isSessionAware()); + handlePeerUnavailability(msg, cause); + } + } + catch (Exception e) { + logger.error("Failure handling send failure error in handleRetransmissionDueToError", e); } - - handleRetransmission(eventType, imsg, false); - imsg.decrementNumberOfRetransAllowed(); } - protected void handleRetransmissionDueToTimeout(Type eventType, Message msg) { - handleRetransmission(eventType, (IMessage) msg, true); + protected void handleRetransmissionDueToTimeout(Type eventType, AppEvent event) throws InternalException { + if (isSessionFailoverSupported()) { + handleRetransmission(eventType, (IMessage) event.getMessage(), true); + } + else { + logger.warn("Failed to send message. Failover unsupported for session ID: {}", sessionData.getSessionId()); + if (logger.isDebugEnabled()) { + logger.debug("Failed to send message, type: {} message: {}, failure: Failover unsupported for session ID: {}", new Object[]{eventType, event + .getMessage(), sessionData.getSessionId()}); + } + handleRetransmissionFailure((RoCreditControlRequest) event); + } } /** @@ -1309,10 +1386,12 @@ protected void dispatch() { setState(ClientRoSessionState.PENDING_BUFFERED); try { dispatchEvent(new AppRequestEventImpl(buffer)); - } catch (Exception e) { + } + catch (Exception e) { try { handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST, buffer); - } catch (Exception e1) { + } + catch (Exception e1) { logger.error("Failure handling buffer send failure", e1); } } @@ -1323,7 +1402,8 @@ protected void dispatch() { if (sessionData.getClientRoSessionState() == ClientRoSessionState.OPEN && eventQueue.size() > 0) { try { this.handleEvent(eventQueue.remove(0)); - } catch (Exception e) { + } + catch (Exception e) { logger.error("Failure handling queued event", e); } } @@ -1336,7 +1416,8 @@ protected void deliverRoAnswer(RoCreditControlRequest request, RoCreditControlAn if (isValid()) { listener.doCreditControlAnswer(this, request, answer); } - } catch (Exception e) { + } + catch (Exception e) { logger.warn("Failure delivering Ro Answer", e); } } @@ -1345,18 +1426,32 @@ protected void deliverRAR(ReAuthRequest request) { logger.debug("Propagating RAR event to listener [{}] on {} session", listener, isValid() ? "valid" : "invalid"); try { listener.doReAuthRequest(this, request); - } catch (Exception e) { + } + catch (Exception e) { logger.warn("Failure delivering RAR", e); } } + protected void deliverRequestTxTimeout(Message msg) { + logger.debug("Propagating Tx timeout event to listener [{}] on {} session", listener, isValid() ? "valid" : "invalid"); + try { + if (isValid()) { + listener.doRequestTxTimeout(this, msg, ((IMessage) msg).getPeer()); + } + } + catch (Exception e) { + logger.warn("Failure delivering request tx timeout", e); + } + } + protected void deliverRequestTimeout(Message msg) { logger.debug("Propagating timeout event to listener [{}] on {} session", listener, isValid() ? "valid" : "invalid"); try { if (isValid()) { listener.doRequestTimeout(this, msg, ((IMessage) msg).getPeer()); } - } catch (Exception e) { + } + catch (Exception e) { logger.warn("Failure delivering request timeout", e); } } @@ -1367,7 +1462,8 @@ protected void deliverPeerUnavailabilityError(Message msg, NoMorePeersAvailableE if (isValid()) { listener.doPeerUnavailability(cause, this, msg, ((IMessage) msg).getPeer()); } - } catch (Exception e) { + } + catch (Exception e) { logger.warn("Failure delivering peer unavailability error", e); } } @@ -1378,14 +1474,16 @@ protected void extractFHAVPs(RoCreditControlRequest request, RoCreditControlAnsw if (answer.isCreditControlFailureHandlingAVPPresent()) { sessionData.setGatheredCCFH(answer.getCredidControlFailureHandlingAVPValue()); } - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } try { if (answer.isDirectDebitingFailureHandlingAVPPresent()) { sessionData.setGatheredDDFH(answer.getDirectDebitingFailureHandlingAVPValue()); } - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Failure trying to obtain Direct-Debit-Failure-Handling AVP value", e); } if (!sessionData.isRequestTypeSet()) { @@ -1393,12 +1491,14 @@ protected void extractFHAVPs(RoCreditControlRequest request, RoCreditControlAnsw // No need to check if it exists.. it must, if not fail with exception sessionData.setEventBased(answer.getRequestTypeAVPValue() == EVENT_REQUEST); } - } else if (request != null) { + } + else if (request != null) { try { if (request.isRequestedActionAVPPresent()) { sessionData.setGatheredRequestedAction(request.getRequestedActionAVPValue()); } - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Failure trying to obtain Request-Action AVP value", e); } @@ -1430,7 +1530,8 @@ protected boolean isSuccess(long resultCode) { } protected boolean isFailure(long code) { - return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && code < 6000)) && !temporaryErrorCodes.contains(code)); + return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && /*code < 4000) || (code >= 5000 &&*/ code < 6000)) && !temporaryErrorCodes.contains + (code)); } protected boolean isRetransmissionRequired() { @@ -1455,7 +1556,6 @@ private TxTimerTask(ClientRoSession session, Request request) { this.request = request; } - @Override public void run() { try { sendAndStateLock.lock(); @@ -1465,13 +1565,17 @@ public void run() { RoCreditControlRequest req = factory.createCreditControlRequest(request); handleEvent(new Event(Event.Type.Tx_TIMER_FIRED, req, null)); - } catch (InternalException e) { + } + catch (InternalException e) { logger.error("Internal Exception", e); - } catch (OverloadException e) { + } + catch (OverloadException e) { logger.error("Overload Exception", e); - } catch (Exception e) { + } + catch (Exception e) { logger.error("Exception", e); - } finally { + } + finally { sendAndStateLock.unlock(); } } @@ -1488,17 +1592,21 @@ private RetransmissionTimerTask(ClientRoSession session, Request request) { public void run() { try { sendAndStateLock.lock(); - logger.debug("Fired failover stop timer"); + logger.debug("Fired failover stop timer (Retransmission timout occured)"); stopTx(false); sessionData.setRetransmissionTimerId(null); handleEvent(new Event(Event.Type.RETRANSMISSION_TIMER_FIRED, factory.createCreditControlRequest(request), null)); - } catch (InternalException e) { + } + catch (InternalException e) { logger.error("Internal Exception", e); - } catch (OverloadException e) { + } + catch (OverloadException e) { logger.error("Overload Exception", e); - } catch (Exception e) { + } + catch (Exception e) { logger.error("Exception", e); - } finally { + } + finally { sendAndStateLock.unlock(); } } @@ -1510,7 +1618,8 @@ private Message messageFromBuffer(ByteBuffer request) throws InternalException { try { m = parser.createMessage(request); return m; - } catch (AvpDataException e) { + } + catch (AvpDataException e) { throw new InternalException("Failed to decode message.", e); } } @@ -1520,7 +1629,8 @@ private Message messageFromBuffer(ByteBuffer request) throws InternalException { private ByteBuffer messageToBuffer(IMessage msg) throws InternalException { try { return parser.encodeMessage(msg); - } catch (ParseException e) { + } + catch (ParseException e) { throw new InternalException("Failed to encode message.", e); } } @@ -1539,11 +1649,10 @@ private class RequestDelivery implements Runnable { ClientRoSession session; Request request; - @Override public void run() { try { switch (request.getCommandCode()) { - case ReAuthAnswer.code: + case ReAuthAnswerImpl.code: handleEvent(new Event(Event.Type.RECEIVED_RAR, factory.createReAuthRequest(request), null)); break; @@ -1551,7 +1660,8 @@ public void run() { listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Failure processing request", e); } } @@ -1562,7 +1672,6 @@ private class AnswerDelivery implements Runnable { Answer answer; Request request; - @Override public void run() { try { switch (request.getCommandCode()) { @@ -1577,7 +1686,8 @@ public void run() { listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Failure processing success message", e); } } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java index a729a31e1..aa46febee 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java @@ -1,44 +1,24 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.client.impl.app.ro; @@ -49,9 +29,9 @@ import java.io.Serializable; /** - * * @author Bartosz Baranowski * @author Alexandre Mendonca + * @author Grzegorz Figiel (ProIDS sp. z o.o.) */ public interface IClientRoSessionData extends IRoSessionData { @@ -94,4 +74,9 @@ public interface IClientRoSessionData extends IRoSessionData { int getGatheredDDFH(); void setGatheredDDFH(int gatheredDDFH); + + int getGatheredCCSF(); + + void setGatheredCCSF(int gatheredCCSF); + } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java index 5ec8db101..e74d92572 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java @@ -42,52 +42,6 @@ package org.jdiameter.client.impl.controller; -import static org.jdiameter.api.Avp.ACCT_APPLICATION_ID; -import static org.jdiameter.api.Avp.AUTH_APPLICATION_ID; -import static org.jdiameter.api.Avp.DESTINATION_HOST; -import static org.jdiameter.api.Avp.DESTINATION_REALM; -import static org.jdiameter.api.Avp.DISCONNECT_CAUSE; -import static org.jdiameter.api.Avp.ERROR_MESSAGE; -import static org.jdiameter.api.Avp.FIRMWARE_REVISION; -import static org.jdiameter.api.Avp.HOST_IP_ADDRESS; -import static org.jdiameter.api.Avp.ORIGIN_HOST; -import static org.jdiameter.api.Avp.ORIGIN_REALM; -import static org.jdiameter.api.Avp.ORIGIN_STATE_ID; -import static org.jdiameter.api.Avp.PRODUCT_NAME; -import static org.jdiameter.api.Avp.RESULT_CODE; -import static org.jdiameter.api.Avp.SUPPORTED_VENDOR_ID; -import static org.jdiameter.api.Avp.VENDOR_ID; -import static org.jdiameter.api.Avp.VENDOR_SPECIFIC_APPLICATION_ID; -import static org.jdiameter.api.Message.CAPABILITIES_EXCHANGE_REQUEST; -import static org.jdiameter.api.Message.DEVICE_WATCHDOG_REQUEST; -import static org.jdiameter.api.Message.DISCONNECT_PEER_REQUEST; -import static org.jdiameter.client.api.fsm.EventTypes.CEA_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.CER_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.CONNECT_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.DISCONNECT_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.DPA_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.DPR_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.DWA_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.DWR_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.INTERNAL_ERROR; -import static org.jdiameter.client.api.fsm.EventTypes.RECEIVE_MSG_EVENT; -import static org.jdiameter.client.api.fsm.EventTypes.STOP_EVENT; -import static org.jdiameter.client.impl.helpers.Parameters.SecurityRef; -import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; @@ -134,6 +88,53 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import static org.jdiameter.api.Avp.ACCT_APPLICATION_ID; +import static org.jdiameter.api.Avp.AUTH_APPLICATION_ID; +import static org.jdiameter.api.Avp.DESTINATION_HOST; +import static org.jdiameter.api.Avp.DESTINATION_REALM; +import static org.jdiameter.api.Avp.DISCONNECT_CAUSE; +import static org.jdiameter.api.Avp.ERROR_MESSAGE; +import static org.jdiameter.api.Avp.FIRMWARE_REVISION; +import static org.jdiameter.api.Avp.HOST_IP_ADDRESS; +import static org.jdiameter.api.Avp.ORIGIN_HOST; +import static org.jdiameter.api.Avp.ORIGIN_REALM; +import static org.jdiameter.api.Avp.ORIGIN_STATE_ID; +import static org.jdiameter.api.Avp.PRODUCT_NAME; +import static org.jdiameter.api.Avp.RESULT_CODE; +import static org.jdiameter.api.Avp.SUPPORTED_VENDOR_ID; +import static org.jdiameter.api.Avp.VENDOR_ID; +import static org.jdiameter.api.Avp.VENDOR_SPECIFIC_APPLICATION_ID; +import static org.jdiameter.api.Message.CAPABILITIES_EXCHANGE_REQUEST; +import static org.jdiameter.api.Message.DEVICE_WATCHDOG_REQUEST; +import static org.jdiameter.api.Message.DISCONNECT_PEER_REQUEST; +import static org.jdiameter.client.api.fsm.EventTypes.CEA_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.CER_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.CONNECT_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.DISCONNECT_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.DPA_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.DPR_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.DWA_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.DWR_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.INTERNAL_ERROR; +import static org.jdiameter.client.api.fsm.EventTypes.RECEIVE_MSG_EVENT; +import static org.jdiameter.client.api.fsm.EventTypes.STOP_EVENT; +import static org.jdiameter.client.impl.helpers.Parameters.PeerRating; +import static org.jdiameter.client.impl.helpers.Parameters.SecurityRef; +import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; + /** * Client Peer implementation * @@ -176,7 +177,6 @@ public class PeerImpl extends AbstractPeer implements IPeer { protected IConnection connection; protected IConnectionListener connListener = new IConnectionListener() { - @Override public void connectionOpened(String connKey) { logger.debug("Connection to {} is open", uri); try { @@ -187,7 +187,6 @@ public void connectionOpened(String connKey) { } } - @Override public void connectionClosed(String connKey, List notSent) { logger.debug("Connection from {} is closed", uri); for (IMessage request : peerRequests.values()) { @@ -211,12 +210,11 @@ public void connectionClosed(String connKey, List notSent) { } } - @Override public void messageReceived(String connKey, IMessage message) { boolean req = message.isRequest(); try { int type = message.getCommandCode(); - logger.debug("Receive message type [{}] to peer [{}]", new Object[] {type, connKey}); + logger.debug("Receive message type [{}] to peer [{}]", new Object[]{type, connKey}); switch (type) { case CAPABILITIES_EXCHANGE_REQUEST: fsm.handleEvent(new FsmEvent(req ? CER_EVENT : CEA_EVENT, message, connKey)); @@ -248,7 +246,6 @@ public void messageReceived(String connKey, IMessage message) { } } - @Override public void internalError(String connKey, IMessage message, TransportException cause) { try { logger.debug("internalError ", cause); @@ -260,20 +257,26 @@ public void internalError(String connKey, IMessage message, TransportException c } }; - public PeerImpl(final PeerTableImpl table, int rating, URI remotePeer, String ip, String portRange, IMetaData metaData, Configuration config, - Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, IStatisticManager statisticFactory, - IConcurrentFactory concurrentFactory, IMessageParser parser, final ISessionDatasource sessionDataSource) throws InternalException, TransportException { + public PeerImpl(final PeerTableImpl table, int rating, URI remotePeer, String ip, String portRange, IMetaData metaData, Configuration config, + Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, IStatisticManager statisticFactory, + IConcurrentFactory concurrentFactory, IMessageParser parser, final ISessionDatasource sessionDataSource) throws InternalException, + TransportException { this(table, rating, remotePeer, ip, portRange, metaData, config, peerConfig, fsmFactory, trFactory, parser, statisticFactory, concurrentFactory, null, sessionDataSource); } protected PeerImpl(final PeerTableImpl table, int rating, URI remotePeer, String ip, String portRange, IMetaData metaData, - Configuration config, Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, - IMessageParser parser, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, - IConnection connection, final ISessionDatasource sessionDataSource) throws InternalException, TransportException { + Configuration config, Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, + IMessageParser parser, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, + IConnection connection, final ISessionDatasource sessionDataSource) throws InternalException, TransportException { super(remotePeer, statisticFactory); this.table = table; - this.rating = rating; + if (peerConfig != null) { + this.rating = peerConfig.getIntValue(PeerRating.ordinal(), 0); + } + else { + this.rating = rating; + } this.router = table.router; this.metaData = metaData; // XXX: FT/HA // this.slc = table.getSessionReqListeners(); @@ -291,7 +294,6 @@ protected PeerImpl(final PeerTableImpl table, int rating, URI remotePeer, String this.fsm = fsmFactory.createInstanceFsm(actionContext, concurrentFactory, config); this.fsm.addStateChangeNotification( new AbstractStateChangeListener() { - @Override public void stateChanged(Enum oldState, Enum newState) { PeerState s = (PeerState) newState; if (PeerState.DOWN.equals(s)) { @@ -324,8 +326,8 @@ public void stateChanged(Enum oldState, Enum newState) { boolean portNotAvailable = false; int limit = 0; int maxTries = endRange - startRange + 1; - logger.debug("Selecting local port randomly from range '{}-{}'. Doing {} tries (some ports may not be tested, others tested more than once).", - new Object[]{startRange, endRange, maxTries}); + logger.debug("Selecting local port randomly from range '{}-{}'. Doing {} tries (some ports may not be tested, others tested more than once).", new + Object[]{startRange, endRange, maxTries}); do { portNotAvailable = false; @@ -366,7 +368,7 @@ public void stateChanged(Enum oldState, Enum newState) { this.connection.addConnectionListener(connListener); } this.parser = parser; - this.addresses = new InetAddress[] {remoteAddress}; + this.addresses = new InetAddress[]{remoteAddress}; this.useUriAsFQDN = config.getBooleanValue(UseUriAsFqdn.ordinal(), (Boolean) UseUriAsFqdn.defValue()); } @@ -383,48 +385,39 @@ private boolean isRedirectAnswer(Avp avpResCode, IMessage answer) { } } - @Override public IStatistic getStatistic() { return statistic; } - @Override public void addPeerStateListener(final PeerStateListener listener) { fsm.addStateChangeNotification(new AbstractStateChangeListener() { - @Override public void stateChanged(Enum oldState, Enum newState) { listener.stateChanged((PeerState) oldState, (PeerState) newState); } - @Override public int hashCode() { return listener.hashCode(); } - @Override public boolean equals(Object obj) { return listener.equals(obj); } }); } - @Override public void removePeerStateListener(final PeerStateListener listener) { //FIXME: fix this... cmon if (listener != null) { fsm.remStateChangeNotification(new AbstractStateChangeListener() { - @Override public void stateChanged(Enum oldState, Enum newState) { listener.stateChanged((PeerState) oldState, (PeerState) newState); } - @Override public int hashCode() { return listener.hashCode(); } - @Override public boolean equals(Object obj) { return listener.equals(obj); } @@ -433,7 +426,7 @@ public boolean equals(Object obj) { } private IMessage processRedirectAnswer(IMessage request, IMessage answer) { - int resultCode = ResultCode.SUCCESS; + int resultCode = ResultCode.SUCCESS; try { //it will try to find next hope and send it... @@ -480,7 +473,6 @@ private IMessage processRedirectAnswer(IMessage request, IMessage answer) { return answer; } - @Override public void connect() throws InternalException, IOException, IllegalDiameterStateException { if (getState(PeerState.class) != PeerState.DOWN) { throw new IllegalDiameterStateException("Invalid state:" + getState(PeerState.class)); @@ -493,7 +485,6 @@ public void connect() throws InternalException, IOException, IllegalDiameterStat } } - @Override public void disconnect(int disconnectCause) throws InternalException, IllegalDiameterStateException { super.disconnect(disconnectCause); if (getState(PeerState.class) != PeerState.DOWN) { @@ -510,74 +501,60 @@ public void disconnect(int disconnectCause) throws InternalException, IllegalDia } } - @Override public E getState(Class enumc) { return fsm.getState(enumc); } - @Override public URI getUri() { return uri; } - @Override public InetAddress[] getIPAddresses() { return addresses; } - @Override public String getRealmName() { return realmName; } - @Override public long getVendorId() { return vendorID; } - @Override public String getProductName() { return productName; } - @Override public long getFirmware() { return firmWare; } - @Override public Set getCommonApplications() { return commonApplications; } - @Override public long getHopByHopIdentifier() { return hopByHopId.incrementAndGet(); } - @Override public void addMessage(IMessage message) { peerRequests.put(message.getHopByHopIdentifier(), message); } - @Override public void remMessage(IMessage message) { peerRequests.remove(message.getHopByHopIdentifier()); } - @Override public IMessage[] remAllMessage() { IMessage[] m = peerRequests.values().toArray(new IMessage[peerRequests.size()]); peerRequests.clear(); return m; } - @Override public boolean handleMessage(EventTypes type, IMessage message, String key) throws TransportException, OverloadException, InternalException { return !stopping && fsm.handleEvent(new FsmEvent(type, message, key)); } - @Override public boolean sendMessage(IMessage message) throws TransportException, OverloadException, InternalException { if (dictionary != null && dictionary.isEnabled()) { logger.debug("Message validation is ENABLED. Going to validate message before sending."); @@ -586,41 +563,34 @@ public boolean sendMessage(IMessage message) throws TransportException, Overload return !stopping && fsm.handleEvent(new FsmEvent(EventTypes.SEND_MSG_EVENT, message)); } - @Override public boolean hasValidConnection() { return connection != null && connection.isConnected(); } - @Override public void setRealm(String realm) { realmName = realm; } - @Override public void addStateChangeListener(StateChangeListener listener) { fsm.addStateChangeNotification(listener); } - @Override public void remStateChangeListener(StateChangeListener listener) { fsm.remStateChangeNotification(listener); } - @Override public void addConnectionListener(IConnectionListener listener) { if (connection != null) { connection.addConnectionListener(listener); } } - @Override public void remConnectionListener(IConnectionListener listener) { if (connection != null) { connection.remConnectionListener(listener); } } - @Override public int getRating() { return rating; } @@ -630,7 +600,6 @@ public boolean isConnected() { return getState(PeerState.class) == PeerState.OKAY; } - @Override public String toString() { return "CPeer{" + "Uri=" + uri + "; State=" + (fsm != null ? fsm.getState(PeerState.class) : "n/a") + "; Rating=" + rating + "; Con=" + connection + "}"; } @@ -673,7 +642,7 @@ else if (r.getAcctAppId() == INT_COMMON_APP_ID || r.getAuthAppId() == INT_COMMON return newAppId; } - protected void sendErrorAnswer(IRequest request, String errorMessage, int resultCode, Avp ...avpsToAdd) { + protected void sendErrorAnswer(IRequest request, String errorMessage, int resultCode, Avp... avpsToAdd) { logger.debug("Could not process request. Result Code = [{}], Error Message: [{}]", resultCode, errorMessage); request.setRequest(false); // Not setting error flag, depends on error code. Will be set @ PeerImpl.ActionContext.sendMessage(IMessage) @@ -715,13 +684,11 @@ protected void sendErrorAnswer(IRequest request, String errorMessage, int result protected class ActionContext implements IContext { - @Override public String toString() { - return new StringBuilder("ActionContext [getPeerDescription()=").append(getPeerDescription()).append(", isConnected()=").append(isConnected()). - append(", isRestoreConnection()=").append(isRestoreConnection()).append("]").toString(); + return new StringBuilder("ActionContext [getPeerDescription()=").append(getPeerDescription()).append(", isConnected()=").append(isConnected()).append + (", isRestoreConnection()=").append(isRestoreConnection()).append("]").toString(); } - @Override public void connect() throws InternalException, IOException, IllegalDiameterStateException { try { connection.connect(); @@ -742,7 +709,6 @@ public void connect() throws InternalException, IOException, IllegalDiameterStat } } - @Override public void disconnect() throws InternalException, IllegalDiameterStateException { if (connection != null) { connection.disconnect(); @@ -752,17 +718,14 @@ public void disconnect() throws InternalException, IllegalDiameterStateException } } - @Override public String getPeerDescription() { return uri.toString(); } - @Override public boolean isConnected() { return (connection != null) && connection.isConnected(); } - @Override public boolean sendMessage(IMessage message) throws TransportException, OverloadException { // Check message if (message.isTimeOut()) { @@ -814,7 +777,6 @@ public boolean sendMessage(IMessage message) throws TransportException, Overload return true; } - @Override public void sendCerMessage() throws TransportException, OverloadException { logger.debug("Send CER message"); IMessage message = parser.createEmptyMessage(CAPABILITIES_EXCHANGE_REQUEST, 0); @@ -842,12 +804,10 @@ public void sendCerMessage() throws TransportException, OverloadException { sendMessage(message); } - @Override public void sendCeaMessage(int resultCode, Message cer, String errMessage) throws TransportException, OverloadException { } - @Override public void sendDwrMessage() throws TransportException, OverloadException { logger.debug("Send DWR message"); IMessage message = parser.createEmptyMessage(DEVICE_WATCHDOG_REQUEST, 0); @@ -864,7 +824,6 @@ public void sendDwrMessage() throws TransportException, OverloadException { sendMessage(message); } - @Override public void sendDwaMessage(IMessage dwr, int resultCode, String errorMessage) throws TransportException, OverloadException { logger.debug("Send DWA message"); IMessage message = parser.createEmptyMessage(dwr); @@ -885,12 +844,10 @@ public void sendDwaMessage(IMessage dwr, int resultCode, String errorMessage) th sendMessage(message); } - @Override public boolean isRestoreConnection() { return true; } - @Override public void sendDprMessage(int disconnectCause) throws TransportException, OverloadException { logger.debug("Send DPR message with Disconnect-Cause [{}]", disconnectCause); IMessage message = parser.createEmptyMessage(DISCONNECT_PEER_REQUEST, 0); @@ -902,14 +859,13 @@ public void sendDprMessage(int disconnectCause) throws TransportException, Overl sendMessage(message); } - @Override public void sendDpaMessage(IMessage dpr, int resultCode, String errorMessage) throws TransportException, OverloadException { logger.debug("Send DPA message"); IMessage message = parser.createEmptyMessage(dpr); message.setRequest(false); message.setHopByHopIdentifier(dpr.getHopByHopIdentifier()); message.setEndToEndIdentifier(dpr.getEndToEndIdentifier()); - message.getAvps().addAvp(RESULT_CODE, resultCode, true, false, true); + message.getAvps().addAvp(RESULT_CODE, resultCode, true, false, true); message.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); message.getAvps().addAvp(ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); if (errorMessage != null) { @@ -918,21 +874,19 @@ public void sendDpaMessage(IMessage dpr, int resultCode, String errorMessage) th sendMessage(message); } - @Override public int processCerMessage(String key, IMessage message) { return 0; } - @Override public boolean processCeaMessage(String key, IMessage message) { boolean rc = true; try { - Avp origHost = message.getAvps().getAvp(ORIGIN_HOST); + Avp origHost = message.getAvps().getAvp(ORIGIN_HOST); Avp origRealm = message.getAvps().getAvp(ORIGIN_REALM); - Avp vendorId = message.getAvps().getAvp(VENDOR_ID); - Avp prdName = message.getAvps().getAvp(PRODUCT_NAME); + Avp vendorId = message.getAvps().getAvp(VENDOR_ID); + Avp prdName = message.getAvps().getAvp(PRODUCT_NAME); Avp resCode = message.getAvps().getAvp(RESULT_CODE); - Avp frmId = message.getAvps().getAvp(FIRMWARE_REVISION); + Avp frmId = message.getAvps().getAvp(FIRMWARE_REVISION); if (origHost == null || origRealm == null || vendorId == null) { logger.warn("Incorrect CEA message (missing mandatory AVPs)"); } @@ -977,7 +931,6 @@ public boolean processCeaMessage(String key, IMessage message) { return rc; } - @Override public boolean receiveMessage(IMessage message) { logger.debug("Receiving message in client."); boolean isProcessed = false; @@ -1066,12 +1019,10 @@ public boolean receiveMessage(IMessage message) { return isProcessed; } - @Override public int processDwrMessage(IMessage iMessage) { return ResultCode.SUCCESS; } - @Override public int processDprMessage(IMessage iMessage) { return ResultCode.SUCCESS; } @@ -1116,7 +1067,6 @@ else if (appId.getAcctAppId() != 0) { /* (non-Javadoc) * @see org.jdiameter.client.api.fsm.IContext#removePeerStatistics() */ - @Override public void removeStatistics() { removePeerStatistics(); } @@ -1124,7 +1074,6 @@ public void removeStatistics() { /* (non-Javadoc) * @see org.jdiameter.client.api.fsm.IContext#createPeerStatistics() */ - @Override public void createStatistics() { createPeerStatistics(); } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java index 39b1b7c59..aa5445d0d 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java @@ -1,54 +1,27 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * JBoss, Home of Professional Open Source + * Copyright 2006, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.client.impl.parser; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; @@ -62,12 +35,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + /** * Represents a Diameter message. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski + * @author Grzegorz Figiel (ProIDS sp. z o.o.) */ public class MessageImpl implements IMessage { @@ -101,7 +82,6 @@ public class MessageImpl implements IMessage { /** * Create empty message * - * @param parser * @param commandCode * @param appId */ @@ -116,7 +96,6 @@ public class MessageImpl implements IMessage { /** * Create empty message * - * @param parser * @param commandCode * @param applicationId * @param flags @@ -172,7 +151,7 @@ private MessageImpl(MessageImpl request) { private String[] routingInfo = {null, null}; private void addRoutingInfo(MessageImpl request) { - for (Avp a :request.getAvps()) { + for (Avp a : request.getAvps()) { if (a.getCode() == Avp.ORIGIN_HOST) { try { routingInfo[0] = a.getDiameterIdentity(); @@ -202,17 +181,14 @@ public String[] getRoutingInfo() { return routingInfo; } - @Override public byte getVersion() { return (byte) version; } - @Override public boolean isRequest() { return (flags & 0x80) != 0; } - @Override public void setRequest(boolean b) { if (b) { flags |= 0x80; @@ -222,12 +198,10 @@ public void setRequest(boolean b) { } } - @Override public boolean isProxiable() { return (flags & 0x40) != 0; } - @Override public void setProxiable(boolean b) { if (b) { flags |= 0x40; @@ -237,12 +211,10 @@ public void setProxiable(boolean b) { } } - @Override public boolean isError() { return (flags & 0x20) != 0; } - @Override public void setError(boolean b) { if (b) { flags |= 0x20; @@ -252,12 +224,10 @@ public void setError(boolean b) { } } - @Override public boolean isReTransmitted() { return (flags & 0x10) != 0; } - @Override public void setReTransmitted(boolean b) { if (b) { flags |= 0x10; @@ -279,8 +249,21 @@ public boolean isRetransmissionAllowed() { return this.numberOfRetransAllowed > 0; } + public int getCcSessionFailover() { + try { + Avp avpCcSessionFailover = avpSet.getAvp(Avp.CC_SESSION_FAILOVER); + if (avpCcSessionFailover != null) { + return avpCcSessionFailover.getInteger32(); + } + } + catch (AvpDataException ade) { + logger.error("Failed to fetch CC-Session-Failover", ade); + } + return SESSION_FAILOVER_NOT_SUPPORTED_VALUE; + } + public void setNumberOfRetransAllowed(int arg) { - if(this.numberOfRetransAllowed < 0) { + if (this.numberOfRetransAllowed < 0) { this.numberOfRetransAllowed = arg; } } @@ -289,12 +272,10 @@ public void decrementNumberOfRetransAllowed() { this.numberOfRetransAllowed--; } - @Override public int getCommandCode() { return this.commandCode; } - @Override public String getSessionId() { try { Avp avpSessionId = avpSet.getAvp(Avp.SESSION_ID); @@ -306,13 +287,11 @@ public String getSessionId() { } } - @Override public Answer createAnswer() { MessageImpl answer = new MessageImpl(this); return answer; } - @Override public Answer createAnswer(long resultCode) { MessageImpl answer = new MessageImpl(this); try { @@ -326,7 +305,6 @@ public Answer createAnswer(long resultCode) { return answer; } - @Override public Answer createAnswer(long vendorId, long experimentalResultCode) { MessageImpl answer = new MessageImpl(this); try { @@ -341,17 +319,14 @@ public Answer createAnswer(long vendorId, long experimentalResultCode) { return answer; } - @Override public long getApplicationId() { return applicationId; } - @Override public ApplicationId getSingleApplicationId() { return getSingleApplicationId(this.applicationId); } - @Override public List getApplicationIdAvps() { if (this.applicationIds != null) { return this.applicationIds; @@ -398,7 +373,6 @@ public List getApplicationIdAvps() { return this.applicationIds; } - @Override public ApplicationId getSingleApplicationId(long applicationId) { logger.debug("In getSingleApplicationId for application id [{}]", applicationId); List appIds = getApplicationIdAvps(); @@ -444,17 +418,14 @@ else if (firstWithZeroVendor != null) { return toReturn; } - @Override public long getHopByHopIdentifier() { return hopByHopId; } - @Override public long getEndToEndIdentifier() { return endToEndId; } - @Override public AvpSet getAvps() { return avpSet; } @@ -462,38 +433,32 @@ public AvpSet getAvps() { protected void copyHeader(MessageImpl request) { endToEndId = request.endToEndId; hopByHopId = request.hopByHopId; - version = request.version; - flags = request.flags; - peer = request.peer; + version = request.version; + flags = request.flags; + peer = request.peer; } - @Override public Avp getResultCode() { return getAvps().getAvp(Avp.RESULT_CODE); } - @Override public void setNetworkRequest(boolean isNetworkRequest) { this.isNetworkRequest = isNetworkRequest; } - @Override public boolean isNetworkRequest() { return isNetworkRequest; } - @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } - @Override public T unwrap(Class aClass) throws InternalException { return null; } // Inner API - @Override public void setHopByHopIdentifier(long hopByHopId) { if (hopByHopId < 0) { this.hopByHopId = -hopByHopId; @@ -506,87 +471,71 @@ public void setHopByHopIdentifier(long hopByHopId) { } } - @Override public void setEndToEndIdentifier(long endByEndId) { this.endToEndId = endByEndId; } - @Override public IPeer getPeer() { return peer; } - @Override public void setPeer(IPeer peer) { this.peer = peer; } - @Override public int getState() { return state; } - @Override public long getHeaderApplicationId() { return applicationId; } - @Override public void setHeaderApplicationId(long applicationId) { this.applicationId = applicationId; } - @Override public int getFlags() { return flags; } - @Override public void setState(int newState) { state = newState; } - @Override public void createTimer(ScheduledExecutorService scheduledFacility, long timeOut, TimeUnit timeUnit) { timerTask = new TimerTask(this); timerTask.setTimerHandler(scheduledFacility, scheduledFacility.schedule(timerTask, timeOut, timeUnit)); } - @Override public void runTimer() { if (timerTask != null && !timerTask.isDone() && !timerTask.isCancelled()) { timerTask.run(); } } - @Override public boolean isTimeOut() { return timerTask != null && timerTask.isDone() && !timerTask.isCancelled(); } - @Override public void setListener(IEventListener listener) { this.listener = listener; } - @Override public IEventListener getEventListener() { return listener; } - @Override public void clearTimer() { if (timerTask != null) { timerTask.cancel(); } } - @Override public String toString() { return "MessageImpl{" + "commandCode=" + commandCode + ", flags=" + flags + '}'; } - @Override public boolean equals(Object o) { if (this == o) { return true; @@ -601,7 +550,6 @@ public boolean equals(Object o) { endToEndId == message.endToEndId && hopByHopId == message.hopByHopId; } - @Override public int hashCode() { long result; result = commandCode; @@ -611,7 +559,6 @@ public int hashCode() { return new Long(result).hashCode(); } - @Override public String getDuplicationKey() { try { return getDuplicationKey(getAvps().getAvp(Avp.ORIGIN_HOST).getDiameterIdentity(), getEndToEndIdentifier()); @@ -622,12 +569,10 @@ public String getDuplicationKey() { } - @Override public String getDuplicationKey(String host, long endToEndId) { return host + endToEndId; } - @Override public Object clone() { try { return parser.createMessage(parser.encodeMessage(this)); @@ -652,12 +597,11 @@ public void setTimerHandler(ScheduledExecutorService scheduledFacility, Schedule this.timerHandler = timerHandler; } - @Override public void run() { try { if (message != null && message.state != STATE_ANSWERED) { IEventListener listener = null; - if (message.listener instanceof IEventListener) { + if (message.listener instanceof IEventListener) { listener = message.listener; } if (listener != null && listener.isValid()) { diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java index fc2743a70..4ffb81307 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/FailureAwareRouter.java @@ -64,20 +64,32 @@ public FailureAwareRouter(IContainer container, IConcurrentFactory concurrentFac if (sds instanceof IRoutingAwareSessionDatasource) { this.sessionDatasource = (IRoutingAwareSessionDatasource) sds; } - if(logger.isDebugEnabled()) { - logger.debug("Constructor for FailureAwareRouter (session persistent routing {})", isSessionPersistentRoutingEnabled() ? "enabled" : "disabled"); - } + + logger.debug("Constructor for FailureAwareRouter (session persistent routing {})", isSessionPersistentRoutingEnabled() ? "enabled" : "disabled"); } /** * Narrows down the subset of peers selected by {@link RouterImpl} superclass to those with * the highest rating only. * - * @see org.jdiameter.client.impl.router.RouterImpl#getAvailablePeers(java.lang.String, java.lang.String[], org.jdiameter.client.api.controller.IPeerTable) + * @see org.jdiameter.client.impl.router.RouterImpl#getAvailablePeers(java.lang.String, java.lang.String[], org.jdiameter.client.api.controller.IPeerTable, + * org.jdiameter.client.api.IMessage) */ @Override - protected List getAvailablePeers(String destRealm, String[] peers, IPeerTable manager) { - List selectedPeers = super.getAvailablePeers(destRealm, peers, manager); + protected List getAvailablePeers(String destRealm, String[] peers, IPeerTable manager, IMessage message) { + List selectedPeers = super.getAvailablePeers(destRealm, peers, manager, message); + + if (logger.isDebugEnabled()) { + logger.debug("All available peers: {}", selectedPeers); + } + selectedPeers = narrowToAnswerablePeers(selectedPeers, message.getSessionId()); + if (logger.isDebugEnabled()) { + logger.debug("All answerable peers: {}", selectedPeers); + } + + if (message.isRetransmissionSupervised()) { + message.setNumberOfRetransAllowed(selectedPeers.size() - 1); + } int maxRating = findMaximumRating(selectedPeers); if (maxRating >= 0 && maxRating != lastSelectedRating) { @@ -85,14 +97,31 @@ protected List getAvailablePeers(String destRealm, String[] peers, IPeerT resetRoundRobinContext(); } - selectedPeers = narrowToRatingBasedSubset(selectedPeers, maxRating); - if(logger.isDebugEnabled()) { - logger.debug("Final subset of peers with rating [{}]: {}", maxRating, selectedPeers); + selectedPeers = narrowToSelectablePeersSubset(selectedPeers, maxRating, message); + if (logger.isDebugEnabled()) { + logger.debug("Final subset of selectable peers (max rating [{}]): {}", maxRating, selectedPeers); } return selectedPeers; } + private List narrowToAnswerablePeers(List availablePeers, String sessionId) { + List unAnswerablePeers = sessionDatasource.getUnanswerablePeers(sessionId); + + if (unAnswerablePeers != null) { + for (String peerFqdn : unAnswerablePeers) { + for (IPeer peer : availablePeers) { + if (peer.getUri().getFQDN().equals(peerFqdn)) { + availablePeers.remove(peer); + break; + } + } + } + } + + return availablePeers; + } + /** * Applies load balancing algorithm and session persistence thereafter if its enabled. * @@ -102,44 +131,30 @@ protected List getAvailablePeers(String destRealm, String[] peers, IPeerT @Override public IPeer selectPeer(List availablePeers, IMessage message) { IPeer peer = null; - String sessionAssignedPeer = null; - - if (isSessionPersistentRoutingEnabled()) { - sessionAssignedPeer = sessionDatasource.getSessionPeer(message.getSessionId()); - if (sessionAssignedPeer != null) { - if(logger.isDebugEnabled()) { - logger.debug("Sticky sessions are enabled and peer [{}] is assigned to the current session [{}]", - new Object[]{sessionAssignedPeer, message.getSessionId()}); - } - peer = findPeer(sessionAssignedPeer, availablePeers); - if (peer != null) { - return peer; - } - else { - if(logger.isDebugEnabled()) { - logger.debug("Peer [{}] assigned to session [{}] so far is not available anymore", sessionAssignedPeer, message.getSessionId()); - } - } - } else { - if(logger.isDebugEnabled()) { - logger.debug("Sticky sessions are enabled and no peer has been yet assigned to the current session [{}]", message.getSessionId()); - } - } - } - - if(logger.isDebugEnabled()) { + if (logger.isDebugEnabled()) { logger.debug(super.dumpRoundRobinContext()); } peer = super.selectPeer(availablePeers); + if (peer == null) { + return null; + } if (isSessionPersistentRoutingEnabled()) { - if (sessionAssignedPeer != null) { - if(logger.isDebugEnabled()) { - logger.debug("Peer reselection took place from [{}] to [{}] on session [{}]", - new Object[]{sessionAssignedPeer, peer.getUri().getFQDN(), message.getSessionId()}); + String sessionAssignedPeer = sessionDatasource.getSessionPeer(message.getSessionId()); + if (sessionAssignedPeer != null && !peer.getUri().getFQDN().equals(sessionAssignedPeer)) { + if (logger.isDebugEnabled()) { + logger.debug("Peer reselection took place from [{}] to [{}] on session [{}]", new Object[]{sessionAssignedPeer, peer.getUri().getFQDN(), message + .getSessionId()}); } sessionDatasource.setSessionPeer(message.getSessionId(), peer); } + else if (sessionAssignedPeer == null) { + sessionDatasource.setSessionPeer(message.getSessionId(), peer); + if (logger.isDebugEnabled()) { + logger.debug("Peer [{}] selected and assigned to session [{}]", new Object[]{peer.getUri().getFQDN(), message.getSessionId()}); + } + } + } return peer; @@ -155,9 +170,9 @@ public boolean isSessionAware() { } /* - * (non-Javadoc) - * @see org.jdiameter.client.impl.router.RouterImpl#getLastSelectedRating() - */ + * (non-Javadoc) + * @see org.jdiameter.client.impl.router.RouterImpl#getLastSelectedRating() + */ @Override protected int getLastSelectedRating() { return this.lastSelectedRating; @@ -195,13 +210,30 @@ public T unwrap(Class aClass) { * *********************** Local helper methods ************************* ***********************************************************************/ - private List narrowToRatingBasedSubset(List peers, int rating) { + private List narrowToSelectablePeersSubset(List peers, int rating, IMessage message) { List peersSubset = new ArrayList(5); + String sessionAssignedPeer = sessionDatasource.getSessionPeer(message.getSessionId()); for (IPeer peer : peers) { + if (isSessionPersistentRoutingEnabled() && sessionAssignedPeer != null) { + if (peer.getUri().getFQDN().equals(sessionAssignedPeer)) { + if (logger.isDebugEnabled()) { + logger.debug("Sticky sessions are enabled and peer [{}] is assigned to the current session [{}]", new Object[]{sessionAssignedPeer, message + .getSessionId()}); + } + peersSubset.clear(); + peersSubset.add(peer); + break; + } + } if (peer.getRating() == rating) { peersSubset.add(peer); } } + + if (logger.isDebugEnabled() && sessionAssignedPeer == null) { + logger.debug("Sticky sessions are enabled and no peer has been yet assigned to the current session [{}]", message.getSessionId()); + } + return peersSubset; } @@ -213,15 +245,6 @@ private int findMaximumRating(List peers) { return maxRating; } - private IPeer findPeer(String fqdn, List peers) { - for (IPeer peer : peers) { - if (peer.getUri().getFQDN().equals(fqdn)) { - return peer; - } - } - return null; - } - private boolean isSessionPersistentRoutingEnabled() { return this.sessionDatasource != null; } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java index 9b250c19c..2ae0f7fba 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java @@ -1,43 +1,23 @@ /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. + * JBoss, Home of Professional Open Source + * Copyright 2006-2011, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jdiameter.client.impl.router; @@ -161,9 +141,11 @@ protected void loadConfiguration(Configuration config) { String localHost = config.getStringValue(Parameters.OwnDiameterURI.ordinal(), null); try { this.realmTable.addLocalRealm(localRealm, new URI(localHost).getFQDN()); - } catch (UnknownServiceException use) { + } + catch (UnknownServiceException use) { throw new RuntimeException("Unable to create URI from Own URI config value:" + localHost, use); - } catch (URISyntaxException use) { + } + catch (URISyntaxException use) { throw new RuntimeException("Unable to create URI from Own URI config value:" + localHost, use); } if (config.getChildren(RequestTable.ordinal()) != null) { @@ -204,12 +186,13 @@ protected void loadConfiguration(Configuration config) { long acc = a.getLongValue(AcctApplId.ordinal(), 0); if (auth != 0) { appId = org.jdiameter.api.ApplicationId.createByAuthAppId(vnd, auth); - } else { + } + else { appId = org.jdiameter.api.ApplicationId.createByAccAppId(vnd, acc); } if (logger.isDebugEnabled()) { - logger.debug("Realm [{}] has application Acct [{}] Auth [{}] Vendor [{}]", - new Object[]{name, appId.getAcctAppId(), appId.getAuthAppId(), appId.getVendorId()}); + logger.debug("Realm [{}] has application Acct [{}] Auth [{}] Vendor [{}]", new Object[]{name, appId.getAcctAppId(), appId + .getAuthAppId(), appId.getVendorId()}); } break; } @@ -233,7 +216,8 @@ protected void loadConfiguration(Configuration config) { } } this.realmTable.addRealm(name, appId, locAction, agentConfImpl, isDynamic, expirationTime, hosts); - } catch (Exception e) { + } + catch (Exception e) { logger.warn("Unable to append realm entry", e); } } @@ -242,7 +226,6 @@ protected void loadConfiguration(Configuration config) { } } - @Override public void registerRequestRouteInfo(IRequest request) { logger.debug("Entering registerRequestRouteInfo"); if (REQUEST_TABLE_SIZE == 0) { @@ -256,7 +239,7 @@ public void registerRequestRouteInfo(IRequest request) { Avp hostAvp = request.getAvps().getAvp(Avp.ORIGIN_HOST); Avp realmAvp = request.getAvps().getAvp(Avp.ORIGIN_REALM); AnswerEntry entry = new AnswerEntry(hopByHopId, hostAvp != null ? hostAvp.getDiameterIdentity() : null, - realmAvp != null ? realmAvp.getDiameterIdentity() : null); + realmAvp != null ? realmAvp.getDiameterIdentity() : null); int s = requestEntryMap.size(); // PCB added logging @@ -281,9 +264,11 @@ public void registerRequestRouteInfo(IRequest request) { logger.warn("RequestRoute map size is now [{}] after sleeping. Clearing it!", requestEntryMap.size()); requestEntryMap.clear(); } - } catch (Exception e) { + } + catch (Exception e) { logger.warn("Failure trying to clear RequestRoute map", e); - } finally { + } + finally { requestEntryTableLock.unlock(); } } @@ -292,9 +277,11 @@ public void registerRequestRouteInfo(IRequest request) { logger.debug("Adding request key [{}] to RequestRoute map for routing answers back to the requesting peer", messageKey); requestEntryMap.put(messageKey, entry); // requestSortedEntryTable.add(hopByHopId); - } catch (Exception e) { + } + catch (Exception e) { logger.warn("Unable to store route info", e); - } finally { + } + finally { // requestEntryTableLock.writeLock().unlock(); } } @@ -303,10 +290,9 @@ public void registerRequestRouteInfo(IRequest request) { private String makeRoutingKey(Message message) { String sessionId = message.getSessionId(); return new StringBuilder(sessionId != null ? sessionId : "null").append(message.getEndToEndIdentifier()) - .append(message.getHopByHopIdentifier()).toString(); + .append(message.getHopByHopIdentifier()).toString(); } - @Override public String[] getRequestRouteInfo(IMessage message) { if (REQUEST_TABLE_SIZE == 0) { return ((MessageImpl) message).getRoutingInfo(); // using answer stored routing info @@ -320,7 +306,8 @@ public String[] getRequestRouteInfo(IMessage message) { logger.debug("getRequestRouteInfo found host [{}] and realm [{}] for Message key Id [{}]", new Object[]{ans.getHost(), ans.getRealm(), messageKey}); } return new String[]{ans.getHost(), ans.getRealm()}; - } else { + } + else { if (logger.isWarnEnabled()) { logger.warn("Could not find route info for message key [{}]. Table size is [{}]", messageKey, requestEntryMap.size()); } @@ -329,7 +316,6 @@ public String[] getRequestRouteInfo(IMessage message) { } //PCB added - @Override public void garbageCollectRequestRouteInfo(IMessage message) { if (REQUEST_TABLE_SIZE == 0) { return; // we don't have anything to do as we are storing routing info at answer message @@ -339,7 +325,6 @@ public void garbageCollectRequestRouteInfo(IMessage message) { requestEntryMap.remove(messageKey); } - @Override public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException, AvpDataException { logger.debug("Getting a peer for message [{}]", message); //FIXME: add ability to send without matching realm+peer pair?, that is , route based on peer table entries? @@ -365,7 +350,8 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException } matchedRealm = (IRealm) this.realmTable.matchRealm(message); - } else { + } + else { //answer, search info = getRequestRouteInfo(message); if (info != null) { @@ -375,7 +361,8 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException if (destRealm == null) { logger.warn("Destination-Realm was null for hopbyhop id " + message.getHopByHopIdentifier()); } - } else { + } + else { logger.debug("No Host and realm found based on hopbyhop id of the answer associated request"); } //FIXME: if no info, should not send it ? @@ -418,32 +405,30 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException logger.debug("Found a peer using destination host avp [{}] peer is [{}] with a valid connection.", destHost, c); //here matchedRealm MAY return c; - } else { - logger.debug("Finding peer by destination host avp [host={}] did not find anything. Now going to try finding one by destination realm [{}]", - destHost, destRealm); + } + else { + logger.debug("Finding peer by destination host avp [host={}] did not find anything. Now going to try finding one by destination realm [{}]", destHost, + destRealm); String[] peers = matchedRealm.getPeerNames(); if (peers == null || peers.length == 0) { throw new RouteException("Unable to find context by route information [" + destRealm + " ," + destHost + "]"); } - List availablePeers = getAvailablePeers(destRealm, peers, manager); - - if (message.isRetransmissionSupervised()) { - message.setNumberOfRetransAllowed(availablePeers.size() - 1); - } + List availablePeers = getAvailablePeers(destRealm, peers, manager, message); if (logger.isDebugEnabled()) { - logger.debug("Performing Realm routing. Realm [{}] has the following peers available {} from list {}", - new Object[]{destRealm, availablePeers, Arrays.asList(peers)}); + logger.debug("Performing Realm routing. Realm [{}] has the following peers available {} from list {}", new Object[]{destRealm, availablePeers, Arrays + .asList(peers)}); } // Balancing IPeer peer = selectPeer(availablePeers, message); if (peer == null) { throw new NoMorePeersAvailableException( - "Unable to find a valid connection within realm [" + destRealm + "]", - isSessionAware(), dumpRoundRobinContext(), getLastSelectedRating()); - } else { + "Unable to find a valid connection within realm [" + destRealm + "]", + isSessionAware(), dumpRoundRobinContext(), getLastSelectedRating()); + } + else { if (logger.isDebugEnabled()) { logger.debug("Load balancing selected peer with uri [{}]", peer.getUri()); } @@ -453,17 +438,15 @@ public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException } } - protected List getAvailablePeers(String destRealm, String[] peers, IPeerTable manager) { + protected List getAvailablePeers(String destRealm, String[] peers, IPeerTable manager, IMessage message) { return getPeers(destRealm, peers, manager, PeerState.OKAY); } private List getPeers(String destRealm, String[] peers, IPeerTable manager, PeerState state) { List availablePeers = new ArrayList(5); - if (logger.isDebugEnabled()) { - logger.debug("Looping through peers in realm [{}]", destRealm); - } + logger.debug("Looping through peers in realm [{}]", destRealm); for (String peerName : peers) { - IPeer localPeer = (IPeer) manager.getPeer(peerName); + IPeer localPeer = manager.getPeer(peerName); if (logger.isDebugEnabled()) { logger.debug("Checking peer [{}] for name [{}]", new Object[]{localPeer, peerName}); } @@ -472,11 +455,12 @@ private List getPeers(String destRealm, String[] peers, IPeerTable manage if (localPeer.hasValidConnection()) { if (logger.isDebugEnabled()) { logger.debug( - "Found available peer to add to available peer list with uri [{}] with a valid connection", - localPeer.getUri().toString()); + "Found available peer to add to available peer list with uri [{}] with a valid connection", + localPeer.getUri().toString()); } availablePeers.add(localPeer); - } else { + } + else { if (logger.isDebugEnabled()) { logger.debug("Found a peer with uri [{}] with no valid connection", localPeer.getUri()); } @@ -491,12 +475,10 @@ public boolean isSessionAware() { return false; } - @Override public IRealmTable getRealmTable() { return this.realmTable; } - @Override public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable table) throws InternalException, RouteException { try { Avp destinationRealmAvp = request.getAvps().getAvp(Avp.DESTINATION_REALM); @@ -568,24 +550,27 @@ public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable t //yes, possible that this will trigger this procedure twice, but thats worst than locking always. redirectTableLock.writeLock().lock(); trimRedirectTable(); - } finally { + } + finally { redirectTableLock.writeLock().unlock(); } } if (REDIRECT_TABLE_SIZE > redirectTable.size()) { RedirectEntry e = new RedirectEntry(primaryKey, secondaryKey, redirectCacheTime, redirectUsage, redirectHosts, destinationRealm); redirectTable.add(e); - //redirectProcessing(answer, destRealm.getOctetString(), destHost !=null ? destHost.getOctetString():null); + //redirectProcessing(answer,destRealm.getOctetString(),destHost !=null ? destHost.getOctetString():null); //we dont have to elect? updateRoute(request, e.getRedirectHost()); - } else { + } + else { if (redirectHosts != null && redirectHosts.length > 0) { String destHost = redirectHosts[0]; //setRouteInfo(answer, getRealmForPeer(destHost), destHost); updateRoute(request, destHost); } } - } else { + } + else { if (redirectHosts != null && redirectHosts.length > 0) { String destHost = redirectHosts[0]; //setRouteInfo(answer, getRealmForPeer(destHost), destHost); @@ -594,11 +579,14 @@ public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable t } //now send table.sendMessage((IMessage) request); - } catch (AvpDataException exc) { + } + catch (AvpDataException exc) { throw new InternalException(exc); - } catch (IllegalDiameterStateException e) { + } + catch (IllegalDiameterStateException e) { throw new InternalException(e); - } catch (IOException e) { + } + catch (IOException e) { throw new InternalException(e); } } @@ -613,7 +601,8 @@ private void trimRedirectTable() { redirectTable.remove(index); index--; //a trick :) } - } catch (Exception e) { + } + catch (Exception e) { logger.debug("Error in redirect task cleanup.", e); break; } @@ -630,7 +619,6 @@ private void updateRoute(IRequest request, String destHost) { request.getAvps().addAvp(Avp.DESTINATION_HOST, destHost, true, false, true); } - @Override public boolean updateRoute(IRequest message) throws RouteException, AvpDataException { AvpSet set = message.getAvps(); Avp destRealmAvp = set.getAvp(Avp.DESTINATION_REALM); @@ -670,7 +658,7 @@ public boolean updateRoute(IRequest message) throws RouteException, AvpDataExcep break; case REALM_AND_APPLICATION: // Usage type: REALM AND APPLICATION matchedEntry = destRealm != null & appId != null & e.primaryKey != null & e.secondaryKey != null & destRealm.equals(e.primaryKey) - & appId.equals(e.secondaryKey); + & appId.equals(e.secondaryKey); break; case ALL_APPLICATION: // Usage type: ALL APPLICATION matchedEntry = appId != null & e.secondaryKey != null & appId.equals(e.secondaryKey); @@ -692,7 +680,8 @@ public boolean updateRoute(IRequest message) throws RouteException, AvpDataExcep return true; } } - } finally { + } + finally { redirectTableLock.readLock().unlock(); } return false; @@ -702,7 +691,6 @@ protected IPeer getPeerPredProcessing(IMessage message, String destRealm, String return null; } - @Override public void start() { if (isStopped) { //redirectScheduler = concurrentFactory.getScheduledExecutorService(RedirectMessageTimer.name()); @@ -711,7 +699,6 @@ public void start() { } } - @Override public void stop() { isStopped = true; // if (redirectEntryHandler != null) { @@ -732,13 +719,13 @@ public void stop() { //} } - @Override public void destroy() { try { if (!isStopped) { stop(); } - } catch (Exception exc) { + } + catch (Exception exc) { logger.error("Unable to stop router", exc); } @@ -878,7 +865,6 @@ public long getExpiredTime() { return createTime + liveTime; } - @Override public int hashCode() { int result = (primaryKey != null ? primaryKey.hashCode() : 0); result = 31 * result + (secondaryKey != null ? secondaryKey.hashCode() : 0); @@ -888,7 +874,6 @@ public int hashCode() { return result; } - @Override public boolean equals(Object other) { if (other == this) { return true; @@ -897,9 +882,10 @@ public boolean equals(Object other) { if (other instanceof RedirectEntry) { RedirectEntry that = (RedirectEntry) other; return liveTime == that.liveTime && usageType == that.usageType && - Arrays.equals(hosts, that.hosts) && !(primaryKey != null ? !primaryKey.equals(that.primaryKey) : that.primaryKey != null) && - !(secondaryKey != null ? !secondaryKey.equals(that.secondaryKey) : that.secondaryKey != null); - } else { + Arrays.equals(hosts, that.hosts) && !(primaryKey != null ? !primaryKey.equals(that.primaryKey) : that.primaryKey != null) && + !(secondaryKey != null ? !secondaryKey.equals(that.secondaryKey) : that.secondaryKey != null); + } + else { return false; } } @@ -942,7 +928,6 @@ public int hashCode() { return super.hashCode(); } - @Override public boolean equals(Object o) { if (this == o) { return true; @@ -954,9 +939,8 @@ public boolean equals(Object o) { return hopByHopId == that.hopByHopId; } - @Override public String toString() { - return "AnswerEntry {" + "createTime=" + createTime + ", hopByHopId=" + hopByHopId + '}'; + return "AnswerEntry{" + "createTime=" + createTime + ", hopByHopId=" + hopByHopId + '}'; } } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IClientRoSessionContext.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IClientRoSessionContext.java index 98bc3d523..66194c546 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IClientRoSessionContext.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IClientRoSessionContext.java @@ -1,44 +1,24 @@ - /* - * TeleStax, Open Source Cloud Communications - * Copyright 2011-2016, TeleStax Inc. and individual contributors - * by the @authors tag. - * - * This program is free software: you can redistribute it and/or modify - * under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * JBoss, Home of Professional Open Source - * Copyright 2007-2011, Red Hat, Inc. and individual contributors - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ +/* + * JBoss, Home of Professional Open Source + * Copyright 2008, Red Hat, Inc. and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ package org.jdiameter.common.api.app.ro; @@ -51,6 +31,7 @@ * * @author Bartosz Baranowski * @author Alexandre Mendonca + * @author Grzegorz Figiel (ProIDS sp. z o.o.) */ public interface IClientRoSessionContext { @@ -62,6 +43,8 @@ public interface IClientRoSessionContext { int getDefaultDDFHValue(); + int getDefaultCCSFValue(); + void grantAccessOnDeliverFailure(ClientRoSession clientCCASessionImpl, Message request); void denyAccessOnDeliverFailure(ClientRoSession clientCCASessionImpl, Message request); diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java index f130f8952..53715898f 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/IRoutingAwareSessionDatasource.java @@ -25,6 +25,8 @@ import org.jdiameter.api.SessionPersistenceStorage; import org.jdiameter.client.api.controller.IPeer; +import java.util.List; + /** * Extends basic session storage with capabilities of CRUD operations * for session persistence records which bind sessions with peers that @@ -55,4 +57,15 @@ public interface IRoutingAwareSessionDatasource extends ISessionDatasource, Sess * @return peer name that has just been unbound */ String removeSessionPeer(String sessionId); + + /** + * @param sessionId session identifier used as mapping key in session storage + */ + void clearUnanswerablePeers(String sessionId); + + /** + * @param sessionId session identifier used as mapping key in session storage + * @return list of peers that did not answer for request within Tx timer value period + */ + List getUnanswerablePeers(String sessionId); } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java index 61230bb5a..fb5e601a1 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRoutingAwareSessionImpl.java @@ -65,8 +65,8 @@ public abstract class AppRoutingAwareSessionImpl extends AppSessionImpl { public AppRoutingAwareSessionImpl(ISessionDatasource sessionStorage, ISessionFactory sessionFactory, IAppSessionData appSessionData) { super(sessionFactory, appSessionData); peerTable = sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(IPeerTable.class); - sesInactivityTimerVal = sessionFactory.getContainer().getConfiguration().getIntValue(SessionInactivityTimeOut.ordinal(), - (Integer) SessionInactivityTimeOut.defValue()) * 1000; + sesInactivityTimerVal = sessionFactory.getContainer().getConfiguration().getIntValue(SessionInactivityTimeOut.ordinal(), (Integer) + SessionInactivityTimeOut.defValue()) * 1000; if (sessionStorage instanceof IRoutingAwareSessionDatasource) { sessionPersistenceStorage = (IRoutingAwareSessionDatasource) sessionStorage; } @@ -93,20 +93,23 @@ protected void initSessionPersistenceContext(AppEvent reqEvent, AppEvent ansEven try { IPeer peer = null; if (reqEvent.getMessage() instanceof IMessage) { + sessionPersistenceStorage.clearUnanswerablePeers(this.getSessionId()); peer = ((IMessage) reqEvent.getMessage()).getPeer(); } else { - logger.warn("Cannot retrieve message detailed context for session [{}]", this.getSessionId()); + logger.warn("Cannot retrieve message detailed context for Session-Id/activityId [{}]", this.getSessionId()); } if (peer == null) { - logger.warn("Taking peer from AVP as no peer is assigned yet to the following message in session [{}]: [{}]", - this.getSessionId(), reqEvent.getMessage().getAvps()); + logger.warn("Taking peer from Origin-Host AVP as no peer is assigned yet to the following message in session [{}]: [{}]", this.getSessionId(), + reqEvent.getMessage().getAvps()); peer = peerTable.getPeer(ansEvent.getOriginHost()); } sessionPersistenceStorage.setSessionPeer(this.getSessionId(), peer); - logger.debug("Session persistent routing will be enforced for session [{}] with peer [{}]", this.getSessionId(), peer); + if (logger.isDebugEnabled()) { + logger.debug("Session persistent routing will be enforced for Session-Id [{}] with peer [{}]", this.getSessionId(), peer); + } } catch (Exception ex) { logger.error("Cannot update session persistence data, default routing will be applied", ex); diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java index 747c382a4..68097b0eb 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java @@ -39,6 +39,7 @@ import org.jdiameter.api.ro.ServerRoSessionListener; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; +import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.ro.ClientRoSessionImpl; import org.jdiameter.client.impl.app.ro.IClientRoSessionData; @@ -63,6 +64,7 @@ * * @author Alexandre Mendonca * @author Bartosz Baranowski + * @author Grzegorz Figiel (ProIDS sp. z o.o.) */ public class RoSessionFactoryImpl implements IRoSessionFactory, ClientRoSessionListener, ServerRoSessionListener, StateChangeListener, IRoMessageFactory, IServerRoSessionContext, IClientRoSessionContext { @@ -70,6 +72,7 @@ public class RoSessionFactoryImpl implements IRoSessionFactory, ClientRoSessionL // Message timeout value (in milliseconds) protected int defaultDirectDebitingFailureHandling = 0; protected int defaultCreditControlFailureHandling = 0; + protected int defaultCreditControlSessionFailover = IMessage.SESSION_FAILOVER_NOT_SUPPORTED_VALUE; // its seconds protected long defaultValidityTime = 60; @@ -96,8 +99,8 @@ public RoSessionFactoryImpl(SessionFactory sessionFactory) { this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IRoSessionData.class); } - public RoSessionFactoryImpl(SessionFactory sessionFactory, int defaultDirectDebitingFailureHandling, int defaultCreditControlFailureHandling, - long defaultValidityTime, long defaultTxTimerValue) { + public RoSessionFactoryImpl(SessionFactory sessionFactory, int defaultDirectDebitingFailureHandling, int defaultCreditControlFailureHandling, long + defaultValidityTime, long defaultTxTimerValue) { this(sessionFactory); this.defaultDirectDebitingFailureHandling = defaultDirectDebitingFailureHandling; @@ -109,7 +112,6 @@ public RoSessionFactoryImpl(SessionFactory sessionFactory, int defaultDirectDebi /** * @return the clientSessionListener */ - @Override public ClientRoSessionListener getClientSessionListener() { if (clientSessionListener != null) { return clientSessionListener; @@ -120,10 +122,8 @@ public ClientRoSessionListener getClientSessionListener() { } /** - * @param clientSessionListener - * the clientSessionListener to set + * @param clientSessionListener the clientSessionListener to set */ - @Override public void setClientSessionListener(ClientRoSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } @@ -131,7 +131,6 @@ public void setClientSessionListener(ClientRoSessionListener clientSessionListen /** * @return the serverSessionListener */ - @Override public ServerRoSessionListener getServerSessionListener() { if (serverSessionListener != null) { return serverSessionListener; @@ -142,10 +141,8 @@ public ServerRoSessionListener getServerSessionListener() { } /** - * @param serverSessionListener - * the serverSessionListener to set + * @param serverSessionListener the serverSessionListener to set */ - @Override public void setServerSessionListener(ServerRoSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } @@ -153,7 +150,6 @@ public void setServerSessionListener(ServerRoSessionListener serverSessionListen /** * @return the serverContextListener */ - @Override public IServerRoSessionContext getServerContextListener() { if (serverContextListener != null) { return serverContextListener; @@ -164,10 +160,8 @@ public IServerRoSessionContext getServerContextListener() { } /** - * @param serverContextListener - * the serverContextListener to set + * @param serverContextListener the serverContextListener to set */ - @Override public void setServerContextListener(IServerRoSessionContext serverContextListener) { this.serverContextListener = serverContextListener; } @@ -175,7 +169,6 @@ public void setServerContextListener(IServerRoSessionContext serverContextListen /** * @return the clientContextListener */ - @Override public IClientRoSessionContext getClientContextListener() { if (clientContextListener != null) { return clientContextListener; @@ -188,7 +181,6 @@ public IClientRoSessionContext getClientContextListener() { /** * @return the messageFactory */ - @Override public IRoMessageFactory getMessageFactory() { if (messageFactory != null) { return messageFactory; @@ -199,19 +191,15 @@ public IRoMessageFactory getMessageFactory() { } /** - * @param messageFactory - * the messageFactory to set + * @param messageFactory the messageFactory to set */ - @Override public void setMessageFactory(IRoMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** - * @param clientContextListener - * the clientContextListener to set + * @param clientContextListener the clientContextListener to set */ - @Override public void setClientContextListener(IClientRoSessionContext clientContextListener) { this.clientContextListener = clientContextListener; } @@ -224,8 +212,7 @@ public SessionFactory getSessionFactory() { } /** - * @param sessionFactory - * the sessionFactory to set + * @param sessionFactory the sessionFactory to set */ public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; @@ -234,7 +221,6 @@ public void setSessionFactory(SessionFactory sessionFactory) { /** * @return the stateListener */ - @Override public StateChangeListener getStateListener() { if (this.stateListener != null) { return stateListener; @@ -245,15 +231,12 @@ public StateChangeListener getStateListener() { } /** - * @param stateListener - * the stateListener to set + * @param stateListener the stateListener to set */ - @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } - @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { @@ -272,8 +255,8 @@ public AppSession getNewSession(String sessionId, Class aC IClientRoSessionData sessionData = (IClientRoSessionData) this.sessionDataFactory.getAppSessionData(ClientRoSession.class, sessionId); sessionData.setApplicationId(applicationId); - clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), iss, sessionFactory, - this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); + clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), iss, sessionFactory, this.getClientSessionListener(), this + .getClientContextListener(), this.getStateListener()); // this goes first! iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); @@ -322,8 +305,8 @@ public AppSession getSession(String sessionId, Class aClas try { if (aClass == ClientRoSession.class) { IClientRoSessionData sessionData = (IClientRoSessionData) this.sessionDataFactory.getAppSessionData(ClientRoSession.class, sessionId); - ClientRoSessionImpl clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), iss, sessionFactory, - this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); + ClientRoSessionImpl clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), iss, sessionFactory, this.getClientSessionListener + (), this.getClientContextListener(), this.getStateListener()); // this goes first! clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; @@ -349,63 +332,58 @@ else if (aClass == ServerRoSession.class) { // Message Handlers --------------------------------------------------------- - @Override public void doCreditControlRequest(ServerRoSession session, RoCreditControlRequest request) throws InternalException { } - @Override public void doCreditControlAnswer(ClientRoSession session, RoCreditControlRequest request, RoCreditControlAnswer answer) throws InternalException { } - @Override public void doReAuthRequest(ClientRoSession session, ReAuthRequest request) throws InternalException { } - @Override public void doReAuthAnswer(ServerRoSession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException { } - @Override public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { } + public void doRequestTxTimeout(ClientRoSession session, Message msg, Peer peer) throws InternalException { + + } + public void doRequestTimeout(ClientRoSession session, Message msg, Peer peer) throws InternalException { } public void doPeerUnavailability(RouteException cause, ClientRoSession session, Message msg, Peer peer) throws InternalException { + } // Message Factory Methods -------------------------------------------------- - @Override public RoCreditControlAnswer createCreditControlAnswer(Answer answer) { return new RoCreditControlAnswerImpl(answer); } - @Override public RoCreditControlRequest createCreditControlRequest(Request req) { return new RoCreditControlRequestImpl(req); } - @Override public ReAuthAnswer createReAuthAnswer(Answer answer) { return new ReAuthAnswerImpl(answer); } - @Override public ReAuthRequest createReAuthRequest(Request req) { return new ReAuthRequestImpl(req); } // Context Methods ---------------------------------------------------------- - @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Ro SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); @@ -416,7 +394,6 @@ public void stateChanged(Enum oldState, Enum newState) { * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ - @Override @SuppressWarnings("unchecked") public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Ro SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[]{source, oldState, newState}); @@ -424,99 +401,85 @@ public void stateChanged(AppSession source, Enum oldState, Enum newState) { // FIXME: add ctx methods proxy calls! - @Override public void sessionSupervisionTimerExpired(ServerRoSession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } - @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerReStarted(ServerRoSession session, ScheduledFuture future) { // TODO Complete this method. } - @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerStarted(ServerRoSession session, ScheduledFuture future) { // TODO Complete this method. } - @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerStopped(ServerRoSession session, ScheduledFuture future) { // TODO Complete this method. } - @Override public void timeoutExpired(Request request) { // FIXME What should we do when there's a timeout? } - @Override public void denyAccessOnDeliverFailure(ClientRoSession clientRoSessionImpl, Message request) { // TODO Complete this method. } - @Override public void denyAccessOnFailureMessage(ClientRoSession clientRoSessionImpl) { // TODO Complete this method. } - @Override public void denyAccessOnTxExpire(ClientRoSession clientRoSessionImpl) { // this.resourceAdaptor.sessionDestroyed(clientRoSessionImpl.getSessions().get(0).getSessionId(), // clientRoSessionImpl); clientRoSessionImpl.release(); } - @Override public int getDefaultCCFHValue() { return defaultCreditControlFailureHandling; } - @Override + public int getDefaultCCSFValue() { + return defaultCreditControlSessionFailover; + } + public int getDefaultDDFHValue() { return defaultDirectDebitingFailureHandling; } - @Override public long getDefaultTxTimerValue() { return defaultTxTimerValue; } - @Override public void grantAccessOnDeliverFailure(ClientRoSession clientRoSessionImpl, Message request) { // TODO Auto-generated method stub } - @Override public void grantAccessOnFailureMessage(ClientRoSession clientRoSessionImpl) { // TODO Auto-generated method stub } - @Override public void grantAccessOnTxExpire(ClientRoSession clientRoSessionImpl) { // TODO Auto-generated method stub } - @Override public void indicateServiceError(ClientRoSession clientRoSessionImpl) { // TODO Auto-generated method stub } - @Override public void txTimerExpired(ClientRoSession session) { // TODO Auto-generated method stub } - @Override public long[] getApplicationIds() { // FIXME: What should we do here? - return new long[] { 4 }; + return new long[]{4}; } - @Override public long getDefaultValidityTime() { return this.defaultValidityTime; } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java index 2dc9cb863..7b8802d67 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/RoutingAwareDataSource.java @@ -10,6 +10,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Map; @@ -90,8 +91,29 @@ public String removeSessionPeer(String sessionId) { if (se != null && se instanceof RoutingAwareSessionEntry) { String oldPeer = ((RoutingAwareSessionEntry) se).peer; ((RoutingAwareSessionEntry) se).peer = null; + ((RoutingAwareSessionEntry) se).getUnanswerablePeers().add(oldPeer); return oldPeer; - } else { + } + else { + return null; + } + } + + @Override + public void clearUnanswerablePeers(String sessionId) { + SessionEntry se = sessionIdToEntry.get(sessionId); + if (se != null && se instanceof RoutingAwareSessionEntry) { + ((RoutingAwareSessionEntry) se).getUnanswerablePeers().clear(); + } + } + + @Override + public List getUnanswerablePeers(String sessionId) { + SessionEntry se = sessionIdToEntry.get(sessionId); + if (se != null && se instanceof RoutingAwareSessionEntry) { + return ((RoutingAwareSessionEntry) se).getUnanswerablePeers(); + } + else { return null; } } @@ -128,12 +150,18 @@ public List dumpStickySessions(int maxLimit) { * a specific peer that is bound to a particular session. Extra info is used for session persistent routing. */ protected static class RoutingAwareSessionEntry extends SessionEntry { + private List unanswerable = new ArrayList(); String peer; + public List getUnanswerablePeers() { + return unanswerable; + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("RoutingAwareSessionEntry [peer=").append(peer).append(", toString()=").append(super.toString()).append("]"); + builder.append("RoutingAwareSessionEntry [peer=").append(peer).append(", unanswerable=[").append(Arrays.toString(unanswerable.toArray())).append("], " + + "toString()=").append(super.toString()).append("]"); return builder.toString(); } @@ -146,11 +174,10 @@ public String toString() { */ public String preetyPrint(String key, DateFormat dateFormat) { StringBuilder builder = new StringBuilder("{id=["); - builder.append(key) - .append("], peer=[") - .append(peer).append("], timestamp=[") - .append(dateFormat.format(new Date(session.getLastAccessedTime()))) - .append("]}").toString(); + builder.append(key).append("], peer=[").append(peer) + .append("], timestamp=[").append(dateFormat.format(new Date(session.getLastAccessedTime()))) + .append("], unanswerable=[").append(Arrays.toString(unanswerable.toArray())) + .append("]}").toString(); return builder.toString(); } } diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/MutablePeerTableImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/MutablePeerTableImpl.java index 895f52bb9..82311b65f 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/MutablePeerTableImpl.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/MutablePeerTableImpl.java @@ -42,35 +42,6 @@ package org.jdiameter.server.impl; -import static org.jdiameter.client.impl.helpers.Parameters.PeerName; -import static org.jdiameter.client.impl.helpers.Parameters.PeerTable; -import static org.jdiameter.client.impl.helpers.Parameters.StopTimeOut; -import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; -import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.ConnectionTimer; -import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.DuplicationMessageTimer; -import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.PeerOverloadTimer; -import static org.jdiameter.server.impl.helpers.Parameters.AcceptUndefinedPeer; -import static org.jdiameter.server.impl.helpers.Parameters.DuplicateProtection; -import static org.jdiameter.server.impl.helpers.Parameters.DuplicateSize; -import static org.jdiameter.server.impl.helpers.Parameters.DuplicateTimer; -import static org.jdiameter.server.impl.helpers.Parameters.PeerAttemptConnection; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.URISyntaxException; -import java.net.UnknownServiceException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; @@ -100,6 +71,7 @@ import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.controller.PeerTableImpl; +import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.server.api.IFsmFactory; @@ -114,8 +86,35 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.InetAddress; +import java.net.URISyntaxException; +import java.net.UnknownServiceException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import static org.jdiameter.client.impl.helpers.Parameters.PeerName; +import static org.jdiameter.client.impl.helpers.Parameters.StopTimeOut; +import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; +import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.ConnectionTimer; +import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.DuplicationMessageTimer; +import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.PeerOverloadTimer; +import static org.jdiameter.server.impl.helpers.Parameters.AcceptUndefinedPeer; +import static org.jdiameter.server.impl.helpers.Parameters.DuplicateProtection; +import static org.jdiameter.server.impl.helpers.Parameters.DuplicateSize; +import static org.jdiameter.server.impl.helpers.Parameters.DuplicateTimer; +import static org.jdiameter.server.impl.helpers.Parameters.PeerAttemptConnection; + /** - * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski @@ -142,7 +141,7 @@ public class MutablePeerTableImpl extends PeerTableImpl implements IMutablePeerT protected ScheduledFuture duplicationHandler = null; protected ConcurrentHashMap storageAnswers = new ConcurrentHashMap(); - protected boolean isAcceptUndefinedPeer = false; + protected boolean isAcceptUndefinedPeer = false; // Connections handling ----------------------------------------------------- private ConcurrentHashMap incConnections; @@ -190,9 +189,9 @@ public String getDuplicationKey() { } public MutablePeerTableImpl(Configuration config, MetaData metaData, IContainer stack, org.jdiameter.server.api.IRouter router, - ISessionFactory sessionFactory, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, - IMessageParser parser, INetwork network, IOverloadManager ovrManager, - IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory) { + ISessionFactory sessionFactory, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, + IMessageParser parser, INetwork network, IOverloadManager ovrManager, + IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory) { logger.debug("MutablePeerTableImpl is being created"); this.metaData = metaData; this.config = config; @@ -213,8 +212,8 @@ public MutablePeerTableImpl(Configuration config, MetaData metaData, IContainer this.duplicateTimer = config.getLongValue(DuplicateTimer.ordinal(), (Long) DuplicateTimer.defValue()); this.duplicateSize = config.getIntValue(DuplicateSize.ordinal(), (Integer) DuplicateSize.defValue()); } - logger.debug("Duplicate Protection Configuration: Enabled? {}, Timer: {}, Size: {}", - new Object[]{this.duplicateProtection, this.duplicateTimer, this.duplicateSize}); + logger.debug("Duplicate Protection Configuration: Enabled? {}, Timer: {}, Size: {}", new Object[]{this.duplicateProtection, this.duplicateTimer, this + .duplicateSize}); if (predefinedPeerTable == null) { predefinedPeerTable = new CopyOnWriteArraySet(); } @@ -227,12 +226,36 @@ public MutablePeerTableImpl(Configuration config, MetaData metaData, IContainer logger.debug("MutablePeerTableImpl has finished initialisation"); } + protected Configuration getPeerConfig(String fqdn) throws URISyntaxException, UnknownServiceException { + if (logger.isDebugEnabled()) { + logger.debug("Searching configuration for peer fqdn: " + fqdn); + } + Configuration result = null; + Configuration[] peers = config.getChildren(Parameters.PeerTable.ordinal()); + if (peers != null && peers.length > 0) { + for (Configuration peerConfig : peers) { + if (peerConfig.isAttributeExist(PeerName.ordinal())) { + String peerConfigFqdn = new URI(peerConfig.getStringValue(PeerName.ordinal(), "")).getFQDN(); + if (fqdn.equals(peerConfigFqdn)) { + result = peerConfig; + break; + } + } + } + } + if (logger.isDebugEnabled()) { + logger.debug("Peer configuration {}found for FQDN: {}", (result == null ? "not " : ""), fqdn); + } + return result; + } + + @Override protected Peer createPeer(int rating, String uri, String ip, String portRange, MetaData metaData, Configuration globalConfig, - Configuration peerConfig, org.jdiameter.client.api.fsm.IFsmFactory fsmFactory, - org.jdiameter.client.api.io.ITransportLayerFactory transportFactory, - IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, - IMessageParser parser) throws InternalException, TransportException, URISyntaxException, UnknownServiceException { + Configuration peerConfig, org.jdiameter.client.api.fsm.IFsmFactory fsmFactory, + org.jdiameter.client.api.io.ITransportLayerFactory transportFactory, + IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, + IMessageParser parser) throws InternalException, TransportException, URISyntaxException, UnknownServiceException { logger.debug("Creating Peer for URI [{}]", uri); if (predefinedPeerTable == null) { logger.debug("Creating new empty predefined peer table"); @@ -241,7 +264,8 @@ protected Peer createPeer(int rating, String uri, String ip, String portRange, M logger.debug("Adding URI [{}] to predefinedPeerTable", uri); predefinedPeerTable.add(new URI(uri).getFQDN()); if (peerConfig.getBooleanValue(PeerAttemptConnection.ordinal(), false)) { - logger.debug("Peer at URI [{}] is configured to attempt a connection (acting as a client) and a new peer instance will be created and returned", uri); + logger.debug("Peer at URI [{}] is configured to attempt a connection (i.e. acting as a client) and a new peer instance will be created and returned", + uri); return newPeerInstance(rating, new URI(uri), ip, portRange, true, null, metaData, globalConfig, peerConfig, (IFsmFactory) fsmFactory, (ITransportLayerFactory) transportFactory, parser, statisticFactory, concurrentFactory); @@ -253,24 +277,22 @@ protected Peer createPeer(int rating, String uri, String ip, String portRange, M } protected IPeer newPeerInstance(int rating, URI uri, String ip, String portRange, boolean attCnn, IConnection connection, - MetaData metaData, Configuration globalConfig, Configuration peerConfig, IFsmFactory fsmFactory, - ITransportLayerFactory transportFactory, IMessageParser parser, - IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory) - throws URISyntaxException, UnknownServiceException, InternalException, TransportException { + MetaData metaData, Configuration globalConfig, Configuration peerConfig, IFsmFactory fsmFactory, + ITransportLayerFactory transportFactory, IMessageParser parser, + IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory) throws URISyntaxException, + UnknownServiceException, InternalException, TransportException { logger.debug("Creating and returning a new Peer Instance for URI [{}].", uri); return new org.jdiameter.server.impl.PeerImpl( - rating, uri, ip, portRange, attCnn, connection, - this, (org.jdiameter.server.api.IMetaData) metaData, globalConfig, peerConfig, sessionFactory, - fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser, network, ovrManager, sessionDatasource - ); + rating, uri, ip, portRange, attCnn, connection, + this, (org.jdiameter.server.api.IMetaData) metaData, globalConfig, peerConfig, sessionFactory, + fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser, network, ovrManager, sessionDatasource + ); } - @Override public void setPeerTableListener(PeerTableListener peerTableListener) { this.peerTableListener = peerTableListener; } - @Override public boolean elementChanged(int i, Object data) { Configuration newConf = (Configuration) data; stopTimeOut = newConf.getLongValue(StopTimeOut.ordinal(), (Long) StopTimeOut.defValue()); @@ -283,7 +305,6 @@ public boolean isDuplicateProtection() { return duplicateProtection; } - @Override public void start() throws IllegalDiameterStateException, IOException { // TODO: use parent method logger.debug("Starting MutablePeerTableImpl. Starting router, overload scheduler, connection check timer, etc."); router.start(); @@ -291,7 +312,6 @@ public void start() throws IllegalDiameterStateException, IOException { // TODO: overloadScheduler = concurrentFactory.getScheduledExecutorService(PeerOverloadTimer.name()); Runnable overloadTask = new Runnable() { - @Override public void run() { if (ovrManager != null) { for (Peer p : peerTable.values()) { @@ -305,12 +325,11 @@ public void run() { if (duplicateProtection) { duplicationScheduler = concurrentFactory.getScheduledExecutorService(DuplicationMessageTimer.name()); Runnable duplicateTask = new Runnable() { - @Override public void run() { long now = System.currentTimeMillis(); if (logger.isDebugEnabled()) { - logger.debug("Running Duplicate Cleaning Task. Duplicate Storage size is: {}. Removing entries with time <= '{}'", - storageAnswers.size(), now - duplicateTimer); + logger.debug("Running Duplicate Cleaning Task. Duplicate Storage size is: {}. Removing entries with time <= '{}'", storageAnswers.size(), now - + duplicateTimer); } for (StorageEntry s : storageAnswers.values()) { if (s != null && s.getTime() + duplicateTimer <= now) { @@ -326,8 +345,8 @@ public void run() { } } if (logger.isDebugEnabled()) { - logger.debug("Completed Duplicate Cleaning Task. New Duplicate Storage size is: {}. Total task runtime: {}ms", - storageAnswers.size(), System.currentTimeMillis() - now); + logger.debug("Completed Duplicate Cleaning Task. New Duplicate Storage size is: {}. Total task runtime: {}ms", storageAnswers.size(), System + .currentTimeMillis() - now); } } }; @@ -336,7 +355,6 @@ public void run() { // connScheduler = concurrentFactory.getScheduledExecutorService(ConnectionTimer.name()); Runnable connectionCheckTask = new Runnable() { - @Override public void run() { Map connections = getIncConnections(); for (IConnection connection : connections.values()) { @@ -407,25 +425,21 @@ private INetworkGuard createNetworkGuard(final ITransportLayerFactory transportF metaData.getLocalPeer().getIPAddresses(), metaData.getLocalPeer().getUri().getPort(), new INetworkConnectionListener() { - @Override public void newNetworkConnection(final IConnection connection) { //PCB added logging logger.debug("newNetworkConnection. connection [{}]", connection.getKey()); synchronized (regLock) { final IConnectionListener listener = new IConnectionListener() { - @Override public void connectionOpened(String connKey) { logger.debug("Connection [{}] opened", connKey); } - @Override @SuppressWarnings("unchecked") public void connectionClosed(String connKey, List notSended) { logger.debug("Connection [{}] closed", connKey); unregister(true); } - @Override public void messageReceived(String connKey, IMessage message) { logger.debug("Message [{}] received to peer [{}]", message, connKey); if (message.isRequest() && message.getCommandCode() == Message.CAPABILITIES_EXCHANGE_REQUEST) { @@ -445,7 +459,8 @@ public void messageReceived(String connKey, IMessage message) { try { realm = message.getAvps().getAvp(Avp.ORIGIN_REALM).getDiameterIdentity(); logger.debug("Origin-Realm in new received message is [{}]", realm); - } catch (AvpDataException e) { + } + catch (AvpDataException e) { logger.warn("Unable to retrieve find Origin-Realm AVP in CER", e); unregister(true); return; @@ -510,7 +525,7 @@ public void messageReceived(String connKey, IMessage message) { } peer = newPeerInstance(0, uri, connection.getRemoteAddress().getHostAddress(), null, false, connection, - metaData, config, null, fsmFactory, transportFactory, parser, statisticFactory, concurrentFactory); + metaData, config, getPeerConfig(uri.getFQDN()), fsmFactory, transportFactory, parser, statisticFactory, concurrentFactory); logger.debug("Created new peer instance [{}] and adding to peer table", peer); peer.setRealm(realm); appendPeerToPeerTable(peer); @@ -534,7 +549,6 @@ public void messageReceived(String connKey, IMessage message) { } } - @Override public void internalError(String connKey, IMessage message, TransportException cause) { logger.debug("Connection [{}] internalError [{}]", connKey, cause); unregister(true); @@ -563,7 +577,7 @@ public void unregister(boolean release) { } } } - ); + ); } private void appendPeerToPeerTable(IPeer peer) { @@ -585,7 +599,6 @@ private void appendPeerToPeerTable(IPeer peer) { } } - @Override public void stopping(int disconnectCause) { super.stopping(disconnectCause); if (networkGuard != null) { @@ -634,20 +647,12 @@ public void stopping(int disconnectCause) { } - @Override public Peer addPeer(URI peerURI, String realm, boolean connecting) { //TODO: add sKey here, now it adds peer to all realms. //TODO: better, separate addPeer from realm! try { - Configuration peerConfig = null; - Configuration[] peers = config.getChildren(PeerTable.ordinal()); - // find peer config - for (Configuration c : peers) { - if (peerURI.getFQDN().equals(c.getStringValue(PeerName.ordinal(), ""))) { - peerConfig = c; - break; - } - } + Configuration peerConfig = getPeerConfig(peerURI.getFQDN()); + if (peerConfig == null) { peerConfig = new EmptyConfiguration(false).add(PeerAttemptConnection, connecting); } @@ -660,7 +665,7 @@ public Peer addPeer(URI peerURI, String realm, boolean connecting) { appendPeerToPeerTable(peer); boolean found = false; - Collection realms = this.router.getRealmTable().getRealms(realm); + Collection realms = this.router.getRealmTable().getRealms(realm); for (Realm r : realms) { if (r.getName().equals(realm)) { ((IRealm) r).addPeerName(peerURI.toString()); @@ -686,7 +691,6 @@ public Set getAllRealms() { return new HashSet(router.getRealmTable().getRealms()); } - @Override public Peer removePeer(String host) { try { String fqdn = null; @@ -715,7 +719,6 @@ public Peer removePeer(String host) { } } - @Override public Statistic getStatistic(String name) { for (Peer p : peerTable.values()) { if (p.getUri().getFQDN().equals(name)) { @@ -725,7 +728,6 @@ public Statistic getStatistic(String name) { return null; } - @Override public IMessage isDuplicate(IMessage request) { String key = request.getDuplicationKey(); if (key != null && storageAnswers != null) { @@ -735,7 +737,6 @@ public IMessage isDuplicate(IMessage request) { return null; } - @Override public void saveToDuplicate(String key, IMessage answer) { if (storageAnswers != null && storageAnswers.size() < duplicateSize) { if (key != null) { @@ -748,19 +749,16 @@ public void saveToDuplicate(String key, IMessage answer) { } } - @Override public ISessionFactory getSessionFactory() { return sessionFactory; } - @Override public boolean isWrapperFor(Class aClass) throws InternalException { boolean isWrapp = super.isWrapperFor(aClass); return aClass == MutablePeerTable.class || aClass == Network.class || isWrapp; } - @Override public T unwrap(Class aClass) throws InternalException { if (aClass == MutablePeerTable.class) { return assembler.getComponentInstance(aClass);